Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Commit

Permalink
Merge pull request dotnet/coreclr#17432 from stephentoub/portnumericperf
Browse files Browse the repository at this point in the history
Improve {u}int/long.ToString/TryFormat throughput by pre-computing the length

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
  • Loading branch information
stephentoub committed Apr 5, 2018
1 parent 4596d66 commit 7921533
Show file tree
Hide file tree
Showing 3 changed files with 329 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\MemoryManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\TlsOverPerCoreLockedStacksArrayPool.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\Utilities.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\Text\FormattingHelpers.CountDigits.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Byte.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Char.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\CharEnumerator.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace System.Buffers.Text
{
internal static partial class FormattingHelpers
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int CountDigits(ulong value)
{
int digits = 1;
uint part;
if (value >= 10000000)
{
if (value >= 100000000000000)
{
part = (uint)(value / 100000000000000);
digits += 14;
}
else
{
part = (uint)(value / 10000000);
digits += 7;
}
}
else
{
part = (uint)value;
}

if (part < 10)
{
// no-op
}
else if (part < 100)
{
digits += 1;
}
else if (part < 1000)
{
digits += 2;
}
else if (part < 10000)
{
digits += 3;
}
else if (part < 100000)
{
digits += 4;
}
else if (part < 1000000)
{
digits += 5;
}
else
{
Debug.Assert(part < 10000000);
digits += 6;
}

return digits;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int CountDigits(uint value)
{
int digits = 1;
if (value >= 100000)
{
value = value / 100000;
digits += 5;
}

if (value < 10)
{
// no-op
}
else if (value < 100)
{
digits += 1;
}
else if (value < 1000)
{
digits += 2;
}
else if (value < 10000)
{
digits += 3;
}
else
{
Debug.Assert(value < 100000);
digits += 4;
}

return digits;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int CountHexDigits(ulong value)
{
// TODO: When x86 intrinsic support comes online, experiment with implementing this using lzcnt.
// return 16 - (int)((uint)Lzcnt.LeadingZeroCount(value | 1) >> 3);

int digits = 1;

if (value > 0xFFFFFFFF)
{
digits += 8;
value >>= 0x20;
}
if (value > 0xFFFF)
{
digits += 4;
value >>= 0x10;
}
if (value > 0xFF)
{
digits += 2;
value >>= 0x8;
}
if (value > 0xF)
digits++;

return digits;
}
}
}
Loading

0 comments on commit 7921533

Please sign in to comment.