perf: reduce allocations and redundant work across core, JsonPath, Da…#379
Merged
Conversation
…taSets and FSharp Add benchmarks (src/ArgonTests/Benchmarks/) covering every change. All numbers below are probe-measured allocation reductions per operation (net10, Release). serializer - indexed loop in GetMatchingConverter: foreach over IList<T> boxed a List enumerator for every value serialized/deserialized - iterate JsonPropertyCollection/JPropertyKeyedCollection backing lists in hot loops instead of boxing enumerators (SerializeObject, SerializeDynamic, creator path, JObject.WriteTo/GetEnumerator, JContainer copy ctor) - manual IDictionaryEnumerator use in SerializeDictionary: foreach boxed a DictionaryEntry per entry (-34% dictionary serialize) - IsInteger(PrimitiveTypeCode) overload: enum-from-integer deserialization boxed the type code and re-derived it reflectively per value (-51%) - cache string TypeConverters: TypeDescriptor.GetConverter ran per Uri value - track presence only for required/populated properties (-24% with one [JsonRequired] on the type) - identity fast path in ToSeparatedCase for already-snake/kebab dictionary keys (-62%) - HashSet membership + single-pass ForgivingCaseSensitiveFind on the creator path (-42% record deserialize) - record struct key for the enum cache: Tuple allocated per enum op reader - BoxedPrimitives for single-digit reads (-68% single-digit ints) - span double.TryParse: unquoted floats allocated a dead string per token (-47%) - skip the intermediate string token for quoted ReadAsDouble/ReadAsBoolean - trust DateTimeOffset.TryParseExact: dates were parsed twice plus a ToCharArray copy per read (-34%) writer - WritePropertyName(string) no longer round-trips through a span back to a fresh string per property - TryFormat double/float/decimal/Guid/TimeSpan into the pooled writeBuffer instead of intermediate strings (-45..49%) - JavaScriptUtils writes unescaped runs as spans instead of copying through a rented buffer; SearchValues escape scan for strings >= 16 chars (-46% CPU on clean strings, scalar loop kept for short strings where vector setup loses) linq / jsonpath - Descendants() single pointer walk over sibling/parent links instead of nested iterators per depth (22,848 B -> 56 B on a 700-token doc) - drop the redundant duplicate-name hash when parsing object properties - typed JValue construction in ReadContentFrom for known token shapes - static empty converter array in JToken.WriteTo - bounded cache of parsed JPaths (-50% repeated SelectToken) - constant-operand fast path in filter evaluation (-29% filter queries) satellites - memoize DiscriminatedUnionConverter.CanConvert: FSharpType.IsUnion ran per value for every type once registered (-84% and -94% CPU on plain POCOs) - cache closed F# list/map delegates: MakeGenericMethod + Invoke ran per call and wrapped exceptions in TargetInvocationException (-83% list deserialize) - resolve DataTable column names per table instead of per cell (-53%)
This was referenced Jul 6, 2026
Closed
Closed
This was referenced Jul 7, 2026
Bump Argon, DiffEngine, EmptyFiles, Verify and Verify.NUnit
VerifyTests/Verify.Sylvan.Data.Excel#115
Closed
Closed
Closed
Bump Argon, DiffEngine, EmptyFiles and Verify
NServiceBusCommunity/NServiceBus.Community.Serilog#864
Closed
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.
…taSets and FSharp
Add benchmarks (src/ArgonTests/Benchmarks/) covering every change. All numbers below are probe-measured allocation reductions per operation (net10, Release).
serializer
reader
writer
linq / jsonpath
satellites