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

Conversation

@stephentoub
Copy link
Member

As was recently done for Int32/Int64 in #18897, tjis ports the Utf8Parser approach to parsing to UInt32/UIn64.{Try}Parse, specifically for NumberStyles.Integer (the default).

Also fixes an issue discovered in the previous Int32/Int64 changes, where if the input both has an overflow and has a formatting error (e.g. Int32.Parse("12345678910blah"), we would end up throwing whichever error was hit first, which is a change from .NET Core 2.1 and netfx. The FormatException needs to be preferred over the OverflowException, which just means we can't bail early when overflow is detected. I'm putting up another corefx tests PR with more tests that cover this.

(I tried to stay fairly true to the Utf8Parser code, since time and effort was spent tuning those. However, this has yielded a fair amount of duplication now, with code repeated four times for each of Int32, UInt32, Int64, and UInt64. After all of the perf improvements are in, we should look to see whether we can retain almost all of the gains while reducing some of that duplication.)

Contributes to https://github.com/dotnet/corefx/issues/30612
cc: @jkotas, @ahsonkhan, @danmosemsft

Benchmark:

using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Jobs;
using BenchmarkDotNet.Running;

[MemoryDiagnoser]
[InProcess]
public class Benchmark
{
    private static void Main() => BenchmarkRunner.Run<Benchmark>();

    [Benchmark] public uint UInt32Parse1() => uint.Parse("1");
    [Benchmark] public uint UInt32Parse12345() => uint.Parse("12345");
    [Benchmark] public uint UInt32Parse1234567890() => uint.Parse("1234567890");
    [Benchmark] public uint UInt32ParseW0W() => uint.Parse(" 0 ");
    [Benchmark] public bool UInt32TryParseInvalid() => uint.TryParse("123a", out _);

    [Benchmark] public ulong UInt64Parse1() => ulong.Parse("1");
    [Benchmark] public ulong UInt64Parse123456789() => ulong.Parse("123456789");
    [Benchmark] public ulong UInt64Parse12345678901234567890() => ulong.Parse("12345678901234567890");
    [Benchmark] public ulong UInt64ParseW0W() => ulong.Parse(" 0 ");
    [Benchmark] public bool UInt64TryParseInvalid() => ulong.TryParse("123a", out _);
}

Before/After:

Benchmark Before (ns) After (ns) Improvement
UInt32Parse1 73.78 32.13 2.30x
UInt32Parse12345 91.89 35.83 2.56x
UInt32Parse1234567890 127.03 38.99 3.26x
UInt32ParseW0W 79.15 33.25 2.38x
UInt32TryParseInvalid 89.62 42.02 2.13x
UInt64Parse1 80.13 33.08 2.42x
UInt64Parse123456789 117.99 41.03 2.88x
UInt64Parse12345678901234567890 181.83 51.02 3.56x
UInt64ParseW0W 73.44 36.77 2.00x
UInt64TryParseInvalid 83.99 42.6 1.97x

(Note that these numbers are from a different machine than the numbers in the Int32/Int64 PR, so they're not directly comparable to each other.)

As was recently done for Int32/Int64, ports the Utf8Parser approach to parsing to UInt32/UIn64.{Try}Parse, specifically for NumberStyles.Integer (the default).

Also fixes an issue discovered in the previous Int32/Int64 changes, where if the input both has an overflow and has a formatting error (e.g. Int32.Parse("12345678910blah"), we would end up throwing whichever error was hit first, which is a change from .NET Core 2.1 and netfx.  The FormatException needs to be preferred over the OverflowException, which just means we can't bail early when overflow is detected.
@stephentoub stephentoub merged commit ce0a261 into dotnet:master Jul 16, 2018
@stephentoub stephentoub deleted the unsignedparseperf branch July 16, 2018 14:00
dotnet-maestro-bot pushed a commit to dotnet-maestro-bot/corefx that referenced this pull request Jul 16, 2018
…8930)

As was recently done for Int32/Int64, ports the Utf8Parser approach to parsing to UInt32/UIn64.{Try}Parse, specifically for NumberStyles.Integer (the default).

Also fixes an issue discovered in the previous Int32/Int64 changes, where if the input both has an overflow and has a formatting error (e.g. Int32.Parse("12345678910blah"), we would end up throwing whichever error was hit first, which is a change from .NET Core 2.1 and netfx.  The FormatException needs to be preferred over the OverflowException, which just means we can't bail early when overflow is detected.

Signed-off-by: dotnet-bot <[email protected]>
dotnet-maestro-bot pushed a commit to dotnet-maestro-bot/corert that referenced this pull request Jul 16, 2018
…8930)

As was recently done for Int32/Int64, ports the Utf8Parser approach to parsing to UInt32/UIn64.{Try}Parse, specifically for NumberStyles.Integer (the default).

Also fixes an issue discovered in the previous Int32/Int64 changes, where if the input both has an overflow and has a formatting error (e.g. Int32.Parse("12345678910blah"), we would end up throwing whichever error was hit first, which is a change from .NET Core 2.1 and netfx.  The FormatException needs to be preferred over the OverflowException, which just means we can't bail early when overflow is detected.

Signed-off-by: dotnet-bot <[email protected]>
stephentoub added a commit to dotnet/corert that referenced this pull request Jul 16, 2018
…8930)

As was recently done for Int32/Int64, ports the Utf8Parser approach to parsing to UInt32/UIn64.{Try}Parse, specifically for NumberStyles.Integer (the default).

Also fixes an issue discovered in the previous Int32/Int64 changes, where if the input both has an overflow and has a formatting error (e.g. Int32.Parse("12345678910blah"), we would end up throwing whichever error was hit first, which is a change from .NET Core 2.1 and netfx.  The FormatException needs to be preferred over the OverflowException, which just means we can't bail early when overflow is detected.

Signed-off-by: dotnet-bot <[email protected]>
stephentoub added a commit to dotnet/corefx that referenced this pull request Jul 16, 2018
…8930)

As was recently done for Int32/Int64, ports the Utf8Parser approach to parsing to UInt32/UIn64.{Try}Parse, specifically for NumberStyles.Integer (the default).

Also fixes an issue discovered in the previous Int32/Int64 changes, where if the input both has an overflow and has a formatting error (e.g. Int32.Parse("12345678910blah"), we would end up throwing whichever error was hit first, which is a change from .NET Core 2.1 and netfx.  The FormatException needs to be preferred over the OverflowException, which just means we can't bail early when overflow is detected.

Signed-off-by: dotnet-bot <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants