Repository navigation
[Fusion] Look up input object fields by UTF-8 name during variable coercion - #10522
Merged
Merged
Conversation
tobias-tengler
force-pushed
the
tte/fusion-utf8-input-field-lookup
branch
2 times, most recently
from
October 9, 2026 10:40
bd53aa7 to
4ca43dc
Compare
tobias-tengler
marked this pull request as ready for review
October 9, 2026 10:41
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The enum refactor introduces an avoidable array allocation for every enum collection.
1 open finding
What changed in this PR
Optimizes Fusion input-object variable coercion by matching raw UTF-8 property names and reusing cached syntax nodes.
Changes:
- Adds a shared UTF-8 name index.
- Uses UTF-8 lookup with escaped-name fallback.
- Adds lookup and coercion coverage.
| File | Description |
|---|---|
VariableCoercionHelperTests.cs |
Tests escaped JSON field names. |
FusionInputFieldDefinitionCollectionTests.cs |
Tests UTF-8 field lookup. |
JsonVariableCoercion.cs |
Uses UTF-8 lookup and cached names. |
FusionInputFieldDefinition.cs |
Caches each field’s NameNode. |
Utf8NameIndex.cs |
Implements shared UTF-8 indexing. |
FusionInputFieldDefinitionCollection.cs |
Adds span-based field lookup. |
FusionEnumValueCollection.cs |
Adopts the shared index. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Contributor
Patch coverage100.0% of changed lines covered (47/47)
Project coverage: 58.7% (315520/537948 lines) |
…ercion Variable coercion read `JsonProperty.Name` up to three times per input object field and created a new `NameNode` for every coerced field. Fields are now looked up by their raw UTF-8 property name and the coerced `ObjectFieldNode` reuses a `NameNode` cached on the input field definition. Escaped property names fall back to the unescaped lookup.
tobias-tengler
force-pushed
the
tte/fusion-utf8-input-field-lookup
branch
from
October 9, 2026 10:55
4ca43dc to
2fe2abb
Compare
JsonMarshal.GetRawUtf8PropertyName only exists since .NET 10, so the guard now targets NET10_0_OR_GREATER and net8.0 and net9.0 keep the string lookup.
The input field and enum value collections no longer build a sorted byte index per collection. Collections with up to eight accessible entries are scanned with Ascii.Equals, larger ones widen the name into a stack buffer and use the ReadOnlySpan<char> alternate lookup of the existing frozen dictionary. The byte-span lookup lives on the field collection base class. Adds a variable coercion benchmark for the small and large input shapes.
This was referenced Oct 25, 2026
Merged
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.

Variable coercion allocated several objects for every field of an input object variable:
JsonVariableCoercionreadJsonProperty.Nameup to three times per field (field lookup, error path segment and the coercedObjectFieldNode), and each read decodes a new UTF-16 string. Every coerced field also got a newNameNode.This PR looks input fields up by their raw UTF-8 property name.
FusionFieldDefinitionCollection<T>gets aTryGetField(ReadOnlySpan<byte>)overload: collections with up to eight accessible fields are scanned withAscii.Equals, larger ones widen the name into a stack buffer and use theReadOnlySpan<char>alternate lookup of the existing frozen dictionary.FusionEnumValueCollectiondoes the same and drops its sorted byte index, so no collection keeps a second copy of its names. The coercedObjectFieldNodereuses aNameNodecached onFusionInputFieldDefinition, and the error path uses the schema's field name. JSON allows escaping any character of a property name ({"\u0069d": 1}is a valid way to sendid), so a property name containing an escape sequence falls back to the unescaped lookup, only when the UTF-8 lookup misses.JsonMarshal.GetRawUtf8PropertyNameexists since .NET 10, so net8.0 and net9.0 keep the string lookup. Per schema this adds the cachedNameNode(40 B per input field definition) and one lookup struct per collection (16 B on net9.0 and later), nothing else.Benchmarks
VariableCoercionBenchmark(added in this PR), net11 in-process.Small input (2 objects, 5 fields)
mainLarge input with a list of 20 input objects (22 objects, 66 fields)
mainVariable coercion allocates 41% less for the small input and 48% less for the large input, and is 25% and 31% faster.