[LOADED_DOCS: 2 files, no new loads]

Support FixStr for short non-ASCII strings (UTF-8)

Refactored WriteFixStrDirect to encode short non-ASCII strings as FixStr if their UTF-8 byte count is ≤31, not just ASCII. This improves efficiency for short international strings. Also ensured correct buffer sizing and direct UTF-8 encoding. No functional change to project file; property repositioned for clarity.
This commit is contained in:
Loretta 2026-05-04 07:02:13 +02:00
parent 1661ffc4c6
commit 80235c9a3d
2 changed files with 16 additions and 12 deletions

View File

@ -16,8 +16,6 @@
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
</PropertyGroup> </PropertyGroup>
<!-- AOT-mode is publish-time only. <!-- AOT-mode is publish-time only.
@ -47,6 +45,8 @@
Suppress for now so builds succeed; revisit if AOT runtime issues surface beyond ctor metadata. --> Suppress for now so builds succeed; revisit if AOT runtime issues surface beyond ctor metadata. -->
<SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings> <SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>
<TrimmerSingleWarn>false</TrimmerSingleWarn> <TrimmerSingleWarn>false</TrimmerSingleWarn>
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -699,21 +699,25 @@ public static partial class AcBinarySerializer
public void WriteFixStrDirect(string value) public void WriteFixStrDirect(string value)
{ {
var length = value.Length; // Compute UTF-8 byte count up front. FixStr opcode encodes byte count (5-bit field, ≤31).
EnsureCapacity(1 + length); // For ASCII: byte count = char count; for non-ASCII: byte count > char count.
// Bonus over the prior ASCII-only path: short non-ASCII strings (e.g. 8-char Hungarian
var destSpan = _buffer.AsSpan(_position + 1, length); // ≈ 12 bytes) now also fit in FixStr and save the String-marker + VarUInt overhead.
var status = Ascii.FromUtf16(value.AsSpan(), destSpan, out var bytesWritten); var byteCount = Utf8NoBom.GetByteCount(value);
if (byteCount <= BinaryTypeCode.FixStrMaxLength)
if (status == OperationStatus.Done && bytesWritten == length)
{ {
_buffer[_position] = BinaryTypeCode.EncodeFixStr(length); EnsureCapacity(1 + byteCount);
_position += 1 + length; _buffer[_position++] = BinaryTypeCode.EncodeFixStr(byteCount);
Utf8NoBom.GetBytes(value.AsSpan(), _buffer.AsSpan(_position, byteCount));
_position += byteCount;
} }
else else
{ {
_buffer[_position++] = BinaryTypeCode.String; _buffer[_position++] = BinaryTypeCode.String;
WriteStringUtf8Internal(value); EnsureCapacity(VarUIntSize((uint)byteCount) + byteCount);
WriteVarUIntUnsafe((uint)byteCount);
Utf8NoBom.GetBytes(value.AsSpan(), _buffer.AsSpan(_position, byteCount));
_position += byteCount;
} }
} }