Improve validated raw JSON writing performance on ARM64#130514
Closed
EgorBo wants to merge 7 commits into
Closed
Conversation
Use CompareTest for nonzero SIMD masks on ARM64 and avoid temporary UTF-8 buffers when validated raw JSON fits in the writer buffer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 836935ce-8491-4faf-bf6c-6d7e8e6ab92c
Contributor
|
Tagging subscribers to this area: @dotnet/area-system-text-json |
Member
Author
|
@EgorBot -azure_arm -azure_amd -arm -profiler using System.Text;
using System.Text.Json;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Benchmarks).Assembly).Run(args);
[MemoryDiagnoser]
public class Benchmarks
{
// ── TokenSerialization fields ────────────────────────────────────────────
private List<object> _tokenObjects;
[ThreadStatic] static Utf8JsonWriter t_writer;
[ThreadStatic] static MemoryStream t_stream;
[GlobalSetup]
public void Setup()
{
// TokenSerialization
_tokenObjects = new List<object>(200);
for (int i = 0; i < 200; i++)
{
if (i % 3 == 0)
_tokenObjects.Add(GenerateRecordJson(1));
else
_tokenObjects.Add(new Dictionary<string, object>
{
["seq"] = i,
["label"] = $"item_{i}",
["blob"] = new byte[100]
});
}
}
private static string GenerateRecordJson(int targetSizeKb = 150)
{
var sb = new StringBuilder(targetSizeKb * 1024 + 512);
sb.Append("{");
sb.Append("\"TypeName\":\"product\",");
sb.Append("\"CategoryCode\":1,");
sb.Append("\"Label\":\"Product\",");
sb.Append("\"IsAction\":false,");
sb.Append("\"IsActionMember\":false,");
sb.Append("\"IsTrackingEnabled\":true,");
sb.Append("\"IsAvailableLocal\":true,");
sb.Append("\"IsChildRecord\":false,");
sb.Append("\"IsLinksEnabled\":true,");
sb.Append("\"IsCustomRecord\":false,");
sb.Append("\"PrimaryKeyField\":\"productid\",");
sb.Append("\"PrimaryLabelField\":\"title\",");
sb.Append("\"Fields\":[");
int targetBytes = targetSizeKb * 1024;
int fieldIndex = 0;
bool firstField = true;
while (sb.Length < targetBytes - 512)
{
if (!firstField) sb.Append(",");
firstField = false;
sb.Append("{");
sb.Append($"\"TypeName\":\"field_{fieldIndex}\",");
sb.Append($"\"InternalName\":\"Field_{fieldIndex}\",");
sb.Append($"\"FieldType\":\"String\",");
sb.Append($"\"Label\":\"Field {fieldIndex}\",");
sb.Append($"\"MaxSize\":100,");
sb.Append($"\"IsReadable\":true,");
sb.Append($"\"IsCreatable\":true,");
sb.Append($"\"IsUpdatable\":true,");
sb.Append($"\"IsTrackingEnabled\":false,");
sb.Append($"\"IsPrimaryKey\":false,");
sb.Append($"\"IsVirtual\":false,");
sb.Append($"\"Requirement\":\"None\"");
sb.Append("}");
fieldIndex++;
}
sb.Append("]");
sb.Append("}");
return sb.ToString();
}
[Benchmark]
public void TokenSerialization()
{
var stream = t_stream ??= new MemoryStream(64 * 1024);
stream.Position = 0;
stream.SetLength(0);
var writer = t_writer;
if (writer == null)
{
writer = new Utf8JsonWriter(stream, new JsonWriterOptions { SkipValidation = true });
t_writer = writer;
}
else
writer.Reset(stream);
writer.WriteStartObject();
writer.WriteStartArray("Catalog");
foreach (var token in _tokenObjects)
{
if (token is string strToken)
{
if (!string.IsNullOrEmpty(strToken))
writer.WriteRawValue(strToken);
}
else if (token is Dictionary<string, object> dictToken)
{
writer.WriteStartObject();
foreach (var kvp in dictToken)
{
writer.WritePropertyName(kvp.Key);
JsonSerializer.Serialize(writer, kvp.Value);
}
writer.WriteEndObject();
}
}
writer.WriteEndArray();
writer.WriteEndObject();
writer.Flush();
if (stream.Length == 0) throw new Exception("unreachable");
}
} |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR optimizes two ARM64-heavy hot paths: writing validated raw JSON values in System.Text.Json (by avoiding a temporary UTF-8 buffer/copy when the writer already has enough free capacity) and JIT lowering for a common ARM64 vector pattern (emitting cmtst via AdvSimd.CompareTest instead of cmeq+mvn).
Changes:
Utf8JsonWriter: transcode UTF-16 raw JSON directly into the writer buffer when capacity allows, validate before committing, and factor validation into a non-inlined helper.- RyuJIT ARM64 lowering: recognize
Not(CompareEqual(value, Zero))for supported integer vector element types and replace it withCompareTest(value, value).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Raw.cs | Adds a fast-path to transcode directly into the existing writer buffer and extracts raw-value validation to a helper to reduce inlining/code size impact. |
| src/coreclr/jit/lowerarmarch.cpp | Adds an ARM64 lowering transform to produce cmtst for ~(value == 0) vector patterns over supported integer element types. |
|
|
||
| case GT_NOT: | ||
| { | ||
| // ~Vector.Equals(value, Zero) is equivalent to AdvSimd.CompareTest(value, value) for integer elements. |
Revert the System.Text.Json writer changes so the benchmark isolates the ARM64 CompareTest lowering optimization. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 368c0f32-0d14-4790-817b-dd954b9c454b
Member
Author
|
@EgorBot -azure_arm using System.Text;
using System.Text.Json;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Benchmarks).Assembly).Run(args);
[MemoryDiagnoser]
public class Benchmarks
{
// ── TokenSerialization fields ────────────────────────────────────────────
private List<object> _tokenObjects;
[ThreadStatic] static Utf8JsonWriter t_writer;
[ThreadStatic] static MemoryStream t_stream;
[GlobalSetup]
public void Setup()
{
// TokenSerialization
_tokenObjects = new List<object>(200);
for (int i = 0; i < 200; i++)
{
if (i % 3 == 0)
_tokenObjects.Add(GenerateRecordJson(1));
else
_tokenObjects.Add(new Dictionary<string, object>
{
["seq"] = i,
["label"] = $"item_{i}",
["blob"] = new byte[100]
});
}
}
private static string GenerateRecordJson(int targetSizeKb = 150)
{
var sb = new StringBuilder(targetSizeKb * 1024 + 512);
sb.Append("{");
sb.Append("\"TypeName\":\"product\",");
sb.Append("\"CategoryCode\":1,");
sb.Append("\"Label\":\"Product\",");
sb.Append("\"IsAction\":false,");
sb.Append("\"IsActionMember\":false,");
sb.Append("\"IsTrackingEnabled\":true,");
sb.Append("\"IsAvailableLocal\":true,");
sb.Append("\"IsChildRecord\":false,");
sb.Append("\"IsLinksEnabled\":true,");
sb.Append("\"IsCustomRecord\":false,");
sb.Append("\"PrimaryKeyField\":\"productid\",");
sb.Append("\"PrimaryLabelField\":\"title\",");
sb.Append("\"Fields\":[");
int targetBytes = targetSizeKb * 1024;
int fieldIndex = 0;
bool firstField = true;
while (sb.Length < targetBytes - 512)
{
if (!firstField) sb.Append(",");
firstField = false;
sb.Append("{");
sb.Append($"\"TypeName\":\"field_{fieldIndex}\",");
sb.Append($"\"InternalName\":\"Field_{fieldIndex}\",");
sb.Append($"\"FieldType\":\"String\",");
sb.Append($"\"Label\":\"Field {fieldIndex}\",");
sb.Append($"\"MaxSize\":100,");
sb.Append($"\"IsReadable\":true,");
sb.Append($"\"IsCreatable\":true,");
sb.Append($"\"IsUpdatable\":true,");
sb.Append($"\"IsTrackingEnabled\":false,");
sb.Append($"\"IsPrimaryKey\":false,");
sb.Append($"\"IsVirtual\":false,");
sb.Append($"\"Requirement\":\"None\"");
sb.Append("}");
fieldIndex++;
}
sb.Append("]");
sb.Append("}");
return sb.ToString();
}
[Benchmark]
public void TokenSerialization()
{
var stream = t_stream ??= new MemoryStream(64 * 1024);
stream.Position = 0;
stream.SetLength(0);
var writer = t_writer;
if (writer == null)
{
writer = new Utf8JsonWriter(stream, new JsonWriterOptions { SkipValidation = true });
t_writer = writer;
}
else
writer.Reset(stream);
writer.WriteStartObject();
writer.WriteStartArray("Catalog");
foreach (var token in _tokenObjects)
{
if (token is string strToken)
{
if (!string.IsNullOrEmpty(strToken))
writer.WriteRawValue(strToken);
}
else if (token is Dictionary<string, object> dictToken)
{
writer.WriteStartObject();
foreach (var kvp in dictToken)
{
writer.WritePropertyName(kvp.Key);
JsonSerializer.Serialize(writer, kvp.Value);
}
writer.WriteEndObject();
}
}
writer.WriteEndArray();
writer.WriteEndObject();
writer.Flush();
if (stream.Length == 0) throw new Exception("unreachable");
}
} |
Member
Author
|
@EgorBot -azure_arm using System.Text;
using System.Text.Json;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Benchmarks).Assembly).Run(args);
[MemoryDiagnoser]
public class Benchmarks
{
// ── TokenSerialization fields ────────────────────────────────────────────
private List<object> _tokenObjects;
[ThreadStatic] static Utf8JsonWriter t_writer;
[ThreadStatic] static MemoryStream t_stream;
[GlobalSetup]
public void Setup()
{
// TokenSerialization
_tokenObjects = new List<object>(200);
for (int i = 0; i < 200; i++)
{
if (i % 3 == 0)
_tokenObjects.Add(GenerateRecordJson(1));
else
_tokenObjects.Add(new Dictionary<string, object>
{
["seq"] = i,
["label"] = $"item_{i}",
["blob"] = new byte[100]
});
}
}
private static string GenerateRecordJson(int targetSizeKb = 150)
{
var sb = new StringBuilder(targetSizeKb * 1024 + 512);
sb.Append("{");
sb.Append("\"TypeName\":\"product\",");
sb.Append("\"CategoryCode\":1,");
sb.Append("\"Label\":\"Product\",");
sb.Append("\"IsAction\":false,");
sb.Append("\"IsActionMember\":false,");
sb.Append("\"IsTrackingEnabled\":true,");
sb.Append("\"IsAvailableLocal\":true,");
sb.Append("\"IsChildRecord\":false,");
sb.Append("\"IsLinksEnabled\":true,");
sb.Append("\"IsCustomRecord\":false,");
sb.Append("\"PrimaryKeyField\":\"productid\",");
sb.Append("\"PrimaryLabelField\":\"title\",");
sb.Append("\"Fields\":[");
int targetBytes = targetSizeKb * 1024;
int fieldIndex = 0;
bool firstField = true;
while (sb.Length < targetBytes - 512)
{
if (!firstField) sb.Append(",");
firstField = false;
sb.Append("{");
sb.Append($"\"TypeName\":\"field_{fieldIndex}\",");
sb.Append($"\"InternalName\":\"Field_{fieldIndex}\",");
sb.Append($"\"FieldType\":\"String\",");
sb.Append($"\"Label\":\"Field {fieldIndex}\",");
sb.Append($"\"MaxSize\":100,");
sb.Append($"\"IsReadable\":true,");
sb.Append($"\"IsCreatable\":true,");
sb.Append($"\"IsUpdatable\":true,");
sb.Append($"\"IsTrackingEnabled\":false,");
sb.Append($"\"IsPrimaryKey\":false,");
sb.Append($"\"IsVirtual\":false,");
sb.Append($"\"Requirement\":\"None\"");
sb.Append("}");
fieldIndex++;
}
sb.Append("]");
sb.Append("}");
return sb.ToString();
}
[Benchmark]
public void TokenSerialization()
{
var stream = t_stream ??= new MemoryStream(64 * 1024);
stream.Position = 0;
stream.SetLength(0);
var writer = t_writer;
if (writer == null)
{
writer = new Utf8JsonWriter(stream, new JsonWriterOptions { SkipValidation = true });
t_writer = writer;
}
else
writer.Reset(stream);
writer.WriteStartObject();
writer.WriteStartArray("Catalog");
foreach (var token in _tokenObjects)
{
if (token is string strToken)
{
if (!string.IsNullOrEmpty(strToken))
writer.WriteRawValue(strToken);
}
else if (token is Dictionary<string, object> dictToken)
{
writer.WriteStartObject();
foreach (var kvp in dictToken)
{
writer.WritePropertyName(kvp.Key);
JsonSerializer.Serialize(writer, kvp.Value);
}
writer.WriteEndObject();
}
}
writer.WriteEndArray();
writer.WriteEndObject();
writer.Flush();
if (stream.Length == 0) throw new Exception("unreachable");
}
} |
Restore the System.Text.Json writer optimization and remove the ARM64 JIT lowering change so the benchmark isolates the managed implementation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 368c0f32-0d14-4790-817b-dd954b9c454b
Member
Author
|
@EgorBot -azure_arm -aws_arm -amd using System.Text;
using System.Text.Json;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Benchmarks).Assembly).Run(args);
[MemoryDiagnoser]
public class Benchmarks
{
// ── TokenSerialization fields ────────────────────────────────────────────
private List<object> _tokenObjects;
[ThreadStatic] static Utf8JsonWriter t_writer;
[ThreadStatic] static MemoryStream t_stream;
[GlobalSetup]
public void Setup()
{
// TokenSerialization
_tokenObjects = new List<object>(200);
for (int i = 0; i < 200; i++)
{
if (i % 3 == 0)
_tokenObjects.Add(GenerateRecordJson(1));
else
_tokenObjects.Add(new Dictionary<string, object>
{
["seq"] = i,
["label"] = $"item_{i}",
["blob"] = new byte[100]
});
}
}
private static string GenerateRecordJson(int targetSizeKb = 150)
{
var sb = new StringBuilder(targetSizeKb * 1024 + 512);
sb.Append("{");
sb.Append("\"TypeName\":\"product\",");
sb.Append("\"CategoryCode\":1,");
sb.Append("\"Label\":\"Product\",");
sb.Append("\"IsAction\":false,");
sb.Append("\"IsActionMember\":false,");
sb.Append("\"IsTrackingEnabled\":true,");
sb.Append("\"IsAvailableLocal\":true,");
sb.Append("\"IsChildRecord\":false,");
sb.Append("\"IsLinksEnabled\":true,");
sb.Append("\"IsCustomRecord\":false,");
sb.Append("\"PrimaryKeyField\":\"productid\",");
sb.Append("\"PrimaryLabelField\":\"title\",");
sb.Append("\"Fields\":[");
int targetBytes = targetSizeKb * 1024;
int fieldIndex = 0;
bool firstField = true;
while (sb.Length < targetBytes - 512)
{
if (!firstField) sb.Append(",");
firstField = false;
sb.Append("{");
sb.Append($"\"TypeName\":\"field_{fieldIndex}\",");
sb.Append($"\"InternalName\":\"Field_{fieldIndex}\",");
sb.Append($"\"FieldType\":\"String\",");
sb.Append($"\"Label\":\"Field {fieldIndex}\",");
sb.Append($"\"MaxSize\":100,");
sb.Append($"\"IsReadable\":true,");
sb.Append($"\"IsCreatable\":true,");
sb.Append($"\"IsUpdatable\":true,");
sb.Append($"\"IsTrackingEnabled\":false,");
sb.Append($"\"IsPrimaryKey\":false,");
sb.Append($"\"IsVirtual\":false,");
sb.Append($"\"Requirement\":\"None\"");
sb.Append("}");
fieldIndex++;
}
sb.Append("]");
sb.Append("}");
return sb.ToString();
}
[Benchmark]
public void TokenSerialization()
{
var stream = t_stream ??= new MemoryStream(64 * 1024);
stream.Position = 0;
stream.SetLength(0);
var writer = t_writer;
if (writer == null)
{
writer = new Utf8JsonWriter(stream, new JsonWriterOptions { SkipValidation = true });
t_writer = writer;
}
else
writer.Reset(stream);
writer.WriteStartObject();
writer.WriteStartArray("Catalog");
foreach (var token in _tokenObjects)
{
if (token is string strToken)
{
if (!string.IsNullOrEmpty(strToken))
writer.WriteRawValue(strToken);
}
else if (token is Dictionary<string, object> dictToken)
{
writer.WriteStartObject();
foreach (var kvp in dictToken)
{
writer.WritePropertyName(kvp.Key);
JsonSerializer.Serialize(writer, kvp.Value);
}
writer.WriteEndObject();
}
}
writer.WriteEndArray();
writer.WriteEndObject();
writer.Flush();
if (stream.Length == 0) throw new Exception("unreachable");
}
} |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Member
Author
|
@EgorBot -azure_arm -aws_graviton5 -amd using System.Text;
using System.Text.Json;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Benchmarks).Assembly).Run(args);
[MemoryDiagnoser]
public class Benchmarks
{
// ── TokenSerialization fields ────────────────────────────────────────────
private List<object> _tokenObjects;
[ThreadStatic] static Utf8JsonWriter t_writer;
[ThreadStatic] static MemoryStream t_stream;
[GlobalSetup]
public void Setup()
{
// TokenSerialization
_tokenObjects = new List<object>(200);
for (int i = 0; i < 200; i++)
{
if (i % 3 == 0)
_tokenObjects.Add(GenerateRecordJson(1));
else
_tokenObjects.Add(new Dictionary<string, object>
{
["seq"] = i,
["label"] = $"item_{i}",
["blob"] = new byte[100]
});
}
}
private static string GenerateRecordJson(int targetSizeKb = 150)
{
var sb = new StringBuilder(targetSizeKb * 1024 + 512);
sb.Append("{");
sb.Append("\"TypeName\":\"product\",");
sb.Append("\"CategoryCode\":1,");
sb.Append("\"Label\":\"Product\",");
sb.Append("\"IsAction\":false,");
sb.Append("\"IsActionMember\":false,");
sb.Append("\"IsTrackingEnabled\":true,");
sb.Append("\"IsAvailableLocal\":true,");
sb.Append("\"IsChildRecord\":false,");
sb.Append("\"IsLinksEnabled\":true,");
sb.Append("\"IsCustomRecord\":false,");
sb.Append("\"PrimaryKeyField\":\"productid\",");
sb.Append("\"PrimaryLabelField\":\"title\",");
sb.Append("\"Fields\":[");
int targetBytes = targetSizeKb * 1024;
int fieldIndex = 0;
bool firstField = true;
while (sb.Length < targetBytes - 512)
{
if (!firstField) sb.Append(",");
firstField = false;
sb.Append("{");
sb.Append($"\"TypeName\":\"field_{fieldIndex}\",");
sb.Append($"\"InternalName\":\"Field_{fieldIndex}\",");
sb.Append($"\"FieldType\":\"String\",");
sb.Append($"\"Label\":\"Field {fieldIndex}\",");
sb.Append($"\"MaxSize\":100,");
sb.Append($"\"IsReadable\":true,");
sb.Append($"\"IsCreatable\":true,");
sb.Append($"\"IsUpdatable\":true,");
sb.Append($"\"IsTrackingEnabled\":false,");
sb.Append($"\"IsPrimaryKey\":false,");
sb.Append($"\"IsVirtual\":false,");
sb.Append($"\"Requirement\":\"None\"");
sb.Append("}");
fieldIndex++;
}
sb.Append("]");
sb.Append("}");
return sb.ToString();
}
[Benchmark]
public void TokenSerialization()
{
var stream = t_stream ??= new MemoryStream(64 * 1024);
stream.Position = 0;
stream.SetLength(0);
var writer = t_writer;
if (writer == null)
{
writer = new Utf8JsonWriter(stream, new JsonWriterOptions { SkipValidation = true });
t_writer = writer;
}
else
writer.Reset(stream);
writer.WriteStartObject();
writer.WriteStartArray("Catalog");
foreach (var token in _tokenObjects)
{
if (token is string strToken)
{
if (!string.IsNullOrEmpty(strToken))
writer.WriteRawValue(strToken);
}
else if (token is Dictionary<string, object> dictToken)
{
writer.WriteStartObject();
foreach (var kvp in dictToken)
{
writer.WritePropertyName(kvp.Key);
JsonSerializer.Serialize(writer, kvp.Value);
}
writer.WriteEndObject();
}
}
writer.WriteEndArray();
writer.WriteEndObject();
writer.Flush();
if (stream.Length == 0) throw new Exception("unreachable");
}
} |
Member
Author
|
@EgorBot -azure_arm -aws_arm -amd using System.Text;
using System.Text.Json;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(Benchmarks).Assembly).Run(args);
[MemoryDiagnoser]
public class Benchmarks
{
// ── TokenSerialization fields ────────────────────────────────────────────
private List<object> _tokenObjects;
[ThreadStatic] static Utf8JsonWriter t_writer;
[ThreadStatic] static MemoryStream t_stream;
[GlobalSetup]
public void Setup()
{
// TokenSerialization
_tokenObjects = new List<object>(200);
for (int i = 0; i < 200; i++)
{
if (i % 3 == 0)
_tokenObjects.Add(GenerateRecordJson(1));
else
_tokenObjects.Add(new Dictionary<string, object>
{
["seq"] = i,
["label"] = $"item_{i}",
["blob"] = new byte[100]
});
}
}
private static string GenerateRecordJson(int targetSizeKb = 150)
{
var sb = new StringBuilder(targetSizeKb * 1024 + 512);
sb.Append("{");
sb.Append("\"TypeName\":\"product\",");
sb.Append("\"CategoryCode\":1,");
sb.Append("\"Label\":\"Product\",");
sb.Append("\"IsAction\":false,");
sb.Append("\"IsActionMember\":false,");
sb.Append("\"IsTrackingEnabled\":true,");
sb.Append("\"IsAvailableLocal\":true,");
sb.Append("\"IsChildRecord\":false,");
sb.Append("\"IsLinksEnabled\":true,");
sb.Append("\"IsCustomRecord\":false,");
sb.Append("\"PrimaryKeyField\":\"productid\",");
sb.Append("\"PrimaryLabelField\":\"title\",");
sb.Append("\"Fields\":[");
int targetBytes = targetSizeKb * 1024;
int fieldIndex = 0;
bool firstField = true;
while (sb.Length < targetBytes - 512)
{
if (!firstField) sb.Append(",");
firstField = false;
sb.Append("{");
sb.Append($"\"TypeName\":\"field_{fieldIndex}\",");
sb.Append($"\"InternalName\":\"Field_{fieldIndex}\",");
sb.Append($"\"FieldType\":\"String\",");
sb.Append($"\"Label\":\"Field {fieldIndex}\",");
sb.Append($"\"MaxSize\":100,");
sb.Append($"\"IsReadable\":true,");
sb.Append($"\"IsCreatable\":true,");
sb.Append($"\"IsUpdatable\":true,");
sb.Append($"\"IsTrackingEnabled\":false,");
sb.Append($"\"IsPrimaryKey\":false,");
sb.Append($"\"IsVirtual\":false,");
sb.Append($"\"Requirement\":\"None\"");
sb.Append("}");
fieldIndex++;
}
sb.Append("]");
sb.Append("}");
return sb.ToString();
}
[Benchmark]
public void TokenSerialization()
{
var stream = t_stream ??= new MemoryStream(64 * 1024);
stream.Position = 0;
stream.SetLength(0);
var writer = t_writer;
if (writer == null)
{
writer = new Utf8JsonWriter(stream, new JsonWriterOptions { SkipValidation = true });
t_writer = writer;
}
else
writer.Reset(stream);
writer.WriteStartObject();
writer.WriteStartArray("Catalog");
foreach (var token in _tokenObjects)
{
if (token is string strToken)
{
if (!string.IsNullOrEmpty(strToken))
writer.WriteRawValue(strToken);
}
else if (token is Dictionary<string, object> dictToken)
{
writer.WriteStartObject();
foreach (var kvp in dictToken)
{
writer.WritePropertyName(kvp.Key);
JsonSerializer.Serialize(writer, kvp.Value);
}
writer.WriteEndObject();
}
}
writer.WriteEndArray();
writer.WriteEndObject();
writer.Flush();
if (stream.Length == 0) throw new Exception("unreachable");
}
} |
This was referenced Jul 11, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contributes to #126679.
Just a bunch of AI generated changes to see if they help with the issue