Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 88eb93a

Browse files
authored
Reduce allocation in Index/Range.ToString (#21755)
* Reduce allocation in Index/Range.ToString * Address PR feedback
1 parent b20917f commit 88eb93a

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

src/System.Private.CoreLib/shared/System/Index.cs

+10-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Diagnostics;
6+
57
namespace System
68
{
79
public readonly struct Index : IEquatable<Index>
@@ -28,10 +30,15 @@ public override int GetHashCode()
2830
return _value;
2931
}
3032

31-
public override string ToString()
33+
public override string ToString() => FromEnd ? ToStringFromEnd() : ((uint)Value).ToString();
34+
35+
private string ToStringFromEnd()
3236
{
33-
string str = Value.ToString();
34-
return FromEnd ? "^" + str : str;
37+
Span<char> span = stackalloc char[11]; // 1 for ^ and 10 for longest possible uint value
38+
bool formatted = ((uint)Value).TryFormat(span.Slice(1), out int charsWritten);
39+
Debug.Assert(formatted);
40+
span[0] = '^';
41+
return new string(span.Slice(0, charsWritten + 1));
3542
}
3643

3744
public static implicit operator Index(int value)

src/System.Private.CoreLib/shared/System/Range.cs

+27-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Diagnostics;
6+
57
namespace System
68
{
79
public readonly struct Range : IEquatable<Range>
@@ -35,7 +37,31 @@ public override int GetHashCode()
3537

3638
public override string ToString()
3739
{
38-
return Start + ".." + End;
40+
Span<char> span = stackalloc char[2 + (2 * 11)]; // 2 for "..", then for each index 1 for '^' and 10 for longest possible uint
41+
int charsWritten;
42+
int pos = 0;
43+
44+
if (Start.FromEnd)
45+
{
46+
span[0] = '^';
47+
pos = 1;
48+
}
49+
bool formatted = ((uint)Start.Value).TryFormat(span.Slice(pos), out charsWritten);
50+
Debug.Assert(formatted);
51+
pos += charsWritten;
52+
53+
span[pos++] = '.';
54+
span[pos++] = '.';
55+
56+
if (End.FromEnd)
57+
{
58+
span[pos++] = '^';
59+
}
60+
formatted = ((uint)End.Value).TryFormat(span.Slice(pos), out charsWritten);
61+
Debug.Assert(formatted);
62+
pos += charsWritten;
63+
64+
return new string(span.Slice(0, pos));
3965
}
4066

4167
public static Range Create(Index start, Index end) => new Range(start, end);

0 commit comments

Comments
 (0)