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

Improve {u}int/long.ToString/TryFormat throughput by pre-computing the length #17432

Merged
merged 2 commits into from
Apr 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: sort order

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's wrong with the sort order? Don't we normally put files in a directory before folders in that directory?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know that was what we were doing.

Looking at this file, we seem to be following alphabetical order (only):

    <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\UnicodeCategory.cs" />
    <Compile Include="$(MSBuildThisFileDirectory)System\Guid.cs" />

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW VS inserts items with simple string sort.

Of course it won't ever insert into an imported file like this.

<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