added new method
This commit is contained in:
parent
ea9b14feeb
commit
135b7379c1
@ -7,6 +7,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
|
||||
<PackageReference Include="System.Memory" Version="4.5.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
63
Identity.cs
63
Identity.cs
@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Benchmark
|
||||
@ -20,29 +20,74 @@ namespace Benchmark
|
||||
{
|
||||
identity = default;
|
||||
var position = value.Length;
|
||||
if (!TryGetNumber(value, null, ref position, out var revision)) return false;
|
||||
if (!TryGetNumberOld(ref value, null, ref position, out var revision)) return false;
|
||||
if (value[position] != '-') return false;
|
||||
if (!TryGetNumber(value, 7, ref position, out var index)) return false;
|
||||
if (!TryGetPrefix(value, ref position, out var prefix)) return false;
|
||||
if (!TryGetNumberOld(ref value, 7, ref position, out var index)) return false;
|
||||
if (!TryGetPrefixOld(ref value, ref position, out var prefix)) return false;
|
||||
identity = new Identity(prefix, index, revision);
|
||||
return true; }
|
||||
|
||||
public static bool TryParse(Span<char> value, out Identity identity)
|
||||
{
|
||||
identity = default;
|
||||
var position = value.Length;
|
||||
if (!TryGetNumber(ref value, null, ref position, out var revision)) return false;
|
||||
if (value[position] != '-') return false;
|
||||
if (!TryGetNumber(ref value, 7, ref position, out var index)) return false;
|
||||
if (!TryGetPrefix(ref value, ref position, out var prefix)) return false;
|
||||
identity = new Identity(prefix, index, revision);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryGetPrefix(in string identity, ref int lastPosition, out string prefix)
|
||||
|
||||
private static bool TryGetPrefixOld(ref string identity, ref int lastPosition, out string prefix)
|
||||
{
|
||||
prefix = identity.Remove(lastPosition + 1);
|
||||
prefix = identity[(lastPosition + 1)..];
|
||||
if (prefix.Length < 3) return false;
|
||||
return !prefix.Any(character => character < 'A' || character > 'Z');
|
||||
for (int i = 0; i < prefix.Length; i++)
|
||||
{
|
||||
if (prefix[i] < 'A' || prefix[i] > 'Z') return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryGetNumber(in string identity, int? exactLength, ref int currentPosition, out int revision)
|
||||
private static bool TryGetPrefix(ref Span<char> identity, ref int lastPosition, out string prefix)
|
||||
{
|
||||
var span = identity[(lastPosition + 1)..];
|
||||
prefix = span.ToString();
|
||||
if (span.Length < 3) return false;
|
||||
for (int i = 0; i < span.Length; i++)
|
||||
{
|
||||
if (span[i] < 'A' || span[i] > 'Z') return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryGetNumberOld(ref string identity, int? exactLength, ref int currentPosition, out int revision)
|
||||
{
|
||||
revision = 0;
|
||||
var start = currentPosition;
|
||||
for (currentPosition = start - 1; currentPosition >= 0; currentPosition--)
|
||||
{
|
||||
var current = identity[currentPosition];
|
||||
if(current == '0') continue;
|
||||
if (current == '0') continue;
|
||||
if (current < '1' || current > '9') break;
|
||||
revision += (current - '0') * IntegerPow(10, start - currentPosition - 1);
|
||||
}
|
||||
|
||||
if (exactLength != null && start - (currentPosition + 1) != exactLength) return false;
|
||||
return revision != default;
|
||||
}
|
||||
|
||||
private static bool TryGetNumber(ref Span<char> identity, int? exactLength, ref int currentPosition, out int revision)
|
||||
{
|
||||
revision = 0;
|
||||
var start = currentPosition;
|
||||
for (currentPosition = start - 1; currentPosition >= 0; currentPosition--)
|
||||
{
|
||||
var current = identity[currentPosition];
|
||||
if (current == '0') continue;
|
||||
if (current < '1' || current > '9') break;
|
||||
revision += (current - '0') * IntegerPow(10, start - currentPosition - 1);
|
||||
}
|
||||
|
@ -1,16 +1,29 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
|
||||
namespace Benchmark
|
||||
{
|
||||
[MemoryDiagnoser]
|
||||
//[SimpleJob(RuntimeMoniker.Net472, baseline: true)]
|
||||
[SimpleJob(RuntimeMoniker.NetCoreApp31)]
|
||||
[SimpleJob(RuntimeMoniker.NetCoreApp50)]
|
||||
public class IdentityParser
|
||||
{
|
||||
private const string TestIdentity = "ABZ0000001-1";
|
||||
private char[] TestIdentityChars;
|
||||
|
||||
private readonly Regex _regex = new Regex(@"^(\w{3,})(\d{7})-(\d+)$", RegexOptions.Compiled);
|
||||
|
||||
[GlobalSetup]
|
||||
public void GlobalSetup()
|
||||
{
|
||||
TestIdentityChars = TestIdentity.ToCharArray();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public Identity? Parse1()
|
||||
public Identity? ParseWithRegex()
|
||||
{
|
||||
var match = _regex.Match(TestIdentity);
|
||||
if (!match.Success) return default;
|
||||
@ -21,9 +34,15 @@ namespace Benchmark
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public Identity? Parse2()
|
||||
public Identity? ParseWithoutRegex()
|
||||
{
|
||||
return Identity.TryParse(TestIdentity, out var identity) ? identity : default(Identity?);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public Identity? ParseWithSpanT()
|
||||
{
|
||||
return Identity.TryParse(TestIdentityChars, out var identity) ? identity : default(Identity?);
|
||||
}
|
||||
}
|
||||
}
|
@ -8,11 +8,11 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="nunit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -11,46 +11,46 @@ namespace TestProject1
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test3()
|
||||
public void Test03()
|
||||
{
|
||||
var actual = new TrailingNumberFromString().GetTrailingNumberFromString3();
|
||||
Assert.AreEqual(1234, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test4()
|
||||
public void Test04()
|
||||
{
|
||||
var actual = new TrailingNumberFromString().GetTrailingNumberFromString4();
|
||||
Assert.AreEqual(1234, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test5()
|
||||
public void Test05()
|
||||
{
|
||||
var actual = new TrailingNumberFromString().GetTrailingNumberFromString5();
|
||||
Assert.AreEqual(1234, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test6()
|
||||
public void Test06()
|
||||
{
|
||||
var actual = new IdentityParser().Parse1();
|
||||
var actual = new IdentityParser().ParseWithoutRegex();
|
||||
Assert.AreEqual("ABZ", actual?.Prefix);
|
||||
Assert.AreEqual(1, actual?.Index);
|
||||
Assert.AreEqual(1, actual?.Revision);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test7()
|
||||
public void Test07()
|
||||
{
|
||||
var actual = new IdentityParser().Parse2();
|
||||
var actual = new IdentityParser().ParseWithRegex();
|
||||
Assert.AreEqual("ABZ", actual?.Prefix);
|
||||
Assert.AreEqual(1, actual?.Index);
|
||||
Assert.AreEqual(1, actual?.Revision);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test8()
|
||||
public void Test08()
|
||||
{
|
||||
Assert.IsTrue(Identity.TryParse("TOPFTP0000123-12", out var actual));
|
||||
Assert.AreEqual("TOPFTP", actual.Prefix);
|
||||
@ -59,7 +59,7 @@ namespace TestProject1
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test9()
|
||||
public void Test09()
|
||||
{
|
||||
Assert.IsTrue(Identity.TryParse("WPR1000023-12", out var actual));
|
||||
Assert.AreEqual("WPR", actual.Prefix);
|
||||
@ -77,6 +77,6 @@ namespace TestProject1
|
||||
Assert.IsFalse(Identity.TryParse("NCL0000000-1", out _));
|
||||
Assert.IsFalse(Identity.TryParse("Nc0000001-1", out _));
|
||||
Assert.IsFalse(Identity.TryParse("0000001-1", out _));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user