From a954c5a5f108d877be9703b6b02bcbec67414e60 Mon Sep 17 00:00:00 2001 From: Michael Staib Date: Tue, 24 Mar 2026 18:40:22 +0000 Subject: [PATCH] Improve source result iteration efficiency --- .../Text/Json/SourceResultDocument.Text.cs | 3 +++ .../Text/Json/SourceResultElement.ArrayEnumerator.cs | 4 +++- .../Text/Json/SourceResultElement.ObjectEnumerator.cs | 11 ++++++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultDocument.Text.cs b/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultDocument.Text.cs index db3f54018ae..d83fc08a282 100644 --- a/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultDocument.Text.cs +++ b/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultDocument.Text.cs @@ -269,6 +269,9 @@ internal Cursor GetEndIndex(Cursor cursor, bool includeEndElement) return endId; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal DbRow GetDbRow(Cursor cursor) => _parsedData.Get(cursor); + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int GetEndRowLength(DbRow endRow) => endRow.TokenType is JsonTokenType.EndObject or JsonTokenType.EndArray diff --git a/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultElement.ArrayEnumerator.cs b/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultElement.ArrayEnumerator.cs index dc95eb122aa..8ebf7a57273 100644 --- a/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultElement.ArrayEnumerator.cs +++ b/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultElement.ArrayEnumerator.cs @@ -101,7 +101,9 @@ public bool MoveNext() // Already on an element: jump to just after this element (exclusive), // which is the start of the next element if one exists. - var next = _target._parent.GetEndIndex(_current, includeEndElement: true); + // Inlined from GetEndIndex(_current, includeEndElement: true). + var row = _target._parent.GetDbRow(_current); + var next = row.IsSimpleValue ? _current + 1 : _current + row.NumberOfRows; if (next < _endCursor) { diff --git a/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultElement.ObjectEnumerator.cs b/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultElement.ObjectEnumerator.cs index 1ab229822a8..27fcc2bfdc6 100644 --- a/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultElement.ObjectEnumerator.cs +++ b/src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/SourceResultElement.ObjectEnumerator.cs @@ -110,12 +110,13 @@ public bool MoveNext() } } - // Advance past the current VALUE to the start of the next element. - // GetEndIndex(current, includeEndElement: true) yields the row after the current value. - var afterCurrent = _target._parent.GetEndIndex(_current, includeEndElement: true); + // Advance past the current VALUE to the row after it. + // Inlined from GetEndIndex(_current, includeEndElement: true) to avoid + // the method call overhead, disposed check, and branch on every iteration. + var row = _target._parent.GetDbRow(_current); + var afterCurrent = row.IsSimpleValue ? _current + 1 : _current + row.NumberOfRows; - // After a value, the next row (if any) is the next PropertyName; we need the VALUE, - // so we skip one more row. + // After the value comes the next PropertyName; skip it to reach the VALUE. var nextValue = afterCurrent + 1; if (nextValue < _endCursor)