-
Notifications
You must be signed in to change notification settings - Fork 5k
Improve performance of FormattingHelper.CountDigits(uint) #76519
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Branch-free, table-based lookup implementation.
Tagging subscribers to this area: @dotnet/area-system-runtime Issue DetailsBranch-free, table-based lookup implementation.
private uint[] _values = new uint[] { 1, 1234567890, 12, 123456789, 123, 12345678, 1234, 1234567, 12345, 123456 };
private char[] _scratch = new char[20];
[Benchmark]
[Arguments(1)]
[Arguments(12)]
[Arguments(123)]
[Arguments(1234)]
[Arguments(12345)]
[Arguments(123456)]
[Arguments(1234567)]
[Arguments(12345678)]
[Arguments(123456789)]
[Arguments(1234567890)]
public string FixedLengthToString(uint value) => value.ToString();
[Benchmark]
[Arguments(1)]
[Arguments(12)]
[Arguments(123)]
[Arguments(1234)]
[Arguments(12345)]
[Arguments(123456)]
[Arguments(1234567)]
[Arguments(12345678)]
[Arguments(123456789)]
[Arguments(1234567890)]
public bool FixedLengthTryFormat(uint value) => value.TryFormat(_scratch, out _);
[Benchmark]
public int AllLengthsToString()
{
int sum = 0;
foreach (uint value in _values)
{
sum += value.ToString().Length;
}
return sum;
}
[Benchmark]
public bool AllLengthsTryFormat()
{
bool success = true;
foreach (uint value in _values)
{
success |= value.TryFormat(_scratch, out _);
}
return success;
}
|
@@ -109,36 +111,52 @@ public static int CountDigits(ulong value) | |||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |||
public static int CountDigits(uint value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update CountDigits(ulong value)
above to take advantage of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update
CountDigits(ulong value)
above to take advantage of this?
FYI: There is a 64-bit version in the comments of Lemire's post
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: There is a 64-bit version in the comments of Lemire's post
Which specifically? The variants I'd seen were only good up to a smaller number of bits, like 57.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume Jan meant
if (longValue <= uint.MaxValue)
return CountDigits((uint)longValue);
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More like:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int CountDigits(ulong value)
{
int digits;
uint part;
if (value >= 1_000_000_000)
{
if (part >= 1_000_000_000_000_000_000)
{
part = (uint)(value / 1_000_000_000_000_000_000);
digits = 18;
}
else
{
part = (uint)(value / 1_000_000_000);
digits = 9;
}
}
else
{
part = (uint)value;
digits = 0;
}
return digits + CountDigits(part);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More like
Yeah, that's what I was planning on doing, but I want to experiment.
I'll merge this and follow-up on the 64-bit case. |
Branch-free, table-based lookup implementation.