Introduce no GC string formatter to optimize score string formatting.

This commit is contained in:
2023-01-26 16:52:05 +08:00
parent c015b60dc3
commit 601f64cc61
9 changed files with 2863 additions and 13 deletions

View File

@@ -4,6 +4,7 @@ using Cryville.Common.Pdt;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Text.Formatting;
namespace Cryville.Crtr { namespace Cryville.Crtr {
public class Judge { public class Judge {
@@ -217,7 +218,7 @@ namespace Cryville.Crtr {
scoreDefs.Add(key, s.Value); scoreDefs.Add(key, s.Value);
scores.Add(key, s.Value.init); scores.Add(key, s.Value.init);
scoreStringCache.Add(scoreStringKeys[key], null); scoreStringCache.Add(scoreStringKeys[key], null);
scoreStringSrcs.Add(scoreStringKeys[key], new ScoreStringSrc(scoreStringPool, () => GetScoreString(strkey))); scoreStringSrcs.Add(scoreStringKeys[key], new ScoreStringSrc(scoreStringPool, () => scores[key], scoreDefs[key].format));
} }
} }
void InvalidateScore(int key) { void InvalidateScore(int key) {
@@ -249,30 +250,32 @@ namespace Cryville.Crtr {
return result; return result;
} }
class ScoreStringSrc : PropSrc { class ScoreStringSrc : PropSrc {
readonly Func<string> _cb; readonly Func<float> _cb;
readonly string _format;
readonly ArrayPool<byte> _pool; readonly ArrayPool<byte> _pool;
byte[] _buf; readonly StringBuffer _buf = new StringBuffer();
public ScoreStringSrc(ArrayPool<byte> pool, Func<string> cb) public ScoreStringSrc(ArrayPool<byte> pool, Func<float> cb, string format)
: base(PdtInternalType.String) { : base(PdtInternalType.String) {
_pool = pool; _pool = pool;
_cb = cb; _cb = cb;
_format = string.Format("{{0:{0}}}", format);
} }
public override void Invalidate() { public override void Invalidate() {
base.Invalidate(); if (buf != null) {
if (_buf != null) { _pool.Return(buf);
_pool.Return(_buf); base.Invalidate();
_buf = null;
} }
} }
protected override unsafe void InternalGet() { protected override unsafe void InternalGet() {
var src = _cb(); var src = _cb();
int strlen = src.Length; _buf.Clear();
_buf.AppendFormat(_format, src);
int strlen = _buf.Count;
buf = _pool.Rent(sizeof(int) + strlen * sizeof(char)); buf = _pool.Rent(sizeof(int) + strlen * sizeof(char));
fixed (byte* _ptr = buf) { fixed (byte* _ptr = buf) {
char* ptr = (char*)(_ptr + sizeof(int));
*(int*)_ptr = strlen; *(int*)_ptr = strlen;
int i = 0; char* ptr = (char*)(_ptr + sizeof(int));
foreach (var c in src) ptr[i++] = c; _buf.CopyTo(ptr, 0, strlen);
} }
} }
} }

View File

@@ -3,7 +3,8 @@
"rootNamespace": "", "rootNamespace": "",
"references": [ "references": [
"GUID:d8ea0e0da3ad53a45b65c912ffcacab0", "GUID:d8ea0e0da3ad53a45b65c912ffcacab0",
"GUID:5686e5ee69d0e084c843d61c240d7fdb" "GUID:5686e5ee69d0e084c843d61c240d7fdb",
"GUID:2922aa74af3b2854e81b8a8b286d8206"
], ],
"includePlatforms": [], "includePlatforms": [],
"excludePlatforms": [], "excludePlatforms": [],

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0c0e7d20046652343bdbe3ed52cb0340
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 85c9d5fa7edeb9d4d8737903efc95abd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
{
"name": "StringFormatter",
"rootNamespace": "",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": true
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2922aa74af3b2854e81b8a8b286d8206
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: be273397b1d98a24cb864cb3e05643cd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: