From 41d7ee2c6e91e6ea024d161fc9a36b9b9b1095fe Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sat, 11 Jul 2026 11:42:11 -0700 Subject: [PATCH] Simplify StringBuilder indexer to reuse FindChunkForIndex The get/set indexers open-coded a chunk walk that did two comparisons per hop and traversed the entire chunk list to validate an out-of-range index. Hoist a single `(uint)index >= (uint)Length` bounds check up front so the out-of-range path is O(1) and each hop of the walk is a single comparison, then reuse the existing `FindChunkForIndex` helper for the traversal. Route the throws through `ThrowHelper` so the property bodies stay small enough to inline. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../src/System/Text/StringBuilder.cs | 43 +++++-------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs index 5787996513129a..305795f7d2504f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs @@ -487,46 +487,23 @@ public char this[int index] { get { - StringBuilder? chunk = this; - while (true) + if ((uint)index >= (uint)Length) { - int indexInBlock = index - chunk.m_ChunkOffset; - if (indexInBlock >= 0) - { - if (indexInBlock >= chunk.m_ChunkLength) - { - throw new IndexOutOfRangeException(); - } - return chunk.m_ChunkChars[indexInBlock]; - } - chunk = chunk.m_ChunkPrevious; - if (chunk == null) - { - throw new IndexOutOfRangeException(); - } + ThrowHelper.ThrowIndexOutOfRangeException(); } + + StringBuilder chunk = FindChunkForIndex(index); + return chunk.m_ChunkChars[index - chunk.m_ChunkOffset]; } set { - StringBuilder? chunk = this; - while (true) + if ((uint)index >= (uint)Length) { - int indexInBlock = index - chunk.m_ChunkOffset; - if (indexInBlock >= 0) - { - if (indexInBlock >= chunk.m_ChunkLength) - { - throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexMustBeLess); - } - chunk.m_ChunkChars[indexInBlock] = value; - return; - } - chunk = chunk.m_ChunkPrevious; - if (chunk == null) - { - throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexMustBeLess); - } + ThrowHelper.ThrowArgumentOutOfRange_IndexMustBeLessException(); } + + StringBuilder chunk = FindChunkForIndex(index); + chunk.m_ChunkChars[index - chunk.m_ChunkOffset] = value; } }