initial commit
This commit is contained in:
parent
924d32929b
commit
3c3b9dd7ed
13
.idea/.idea.Benchmark/.idea/.gitignore
generated
vendored
Normal file
13
.idea/.idea.Benchmark/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Rider ignored files
|
||||||
|
/.idea.Benchmark.iml
|
||||||
|
/projectSettingsUpdater.xml
|
||||||
|
/modules.xml
|
||||||
|
/contentModel.xml
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
4
.idea/.idea.Benchmark/.idea/encodings.xml
generated
Normal file
4
.idea/.idea.Benchmark/.idea/encodings.xml
generated
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||||
|
</project>
|
8
.idea/.idea.Benchmark/.idea/indexLayout.xml
generated
Normal file
8
.idea/.idea.Benchmark/.idea/indexLayout.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ContentModelUserStore">
|
||||||
|
<attachedFolders />
|
||||||
|
<explicitIncludes />
|
||||||
|
<explicitExcludes />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/.idea.Benchmark/.idea/misc.xml
generated
Normal file
6
.idea/.idea.Benchmark/.idea/misc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptSettings">
|
||||||
|
<option name="languageLevel" value="ES6" />
|
||||||
|
</component>
|
||||||
|
</project>
|
19
.idea/.idea.Benchmark/riderModule.iml
generated
Normal file
19
.idea/.idea.Benchmark/riderModule.iml
generated
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="RIDER_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/microsoft.diagnostics.tracing.traceevent/2.0.49/lib/native/amd64" />
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/microsoft.diagnostics.tracing.traceevent/2.0.49/lib/native/x86" />
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/microsoft.diagnostics.tracing.traceevent/2.0.49/lib/netstandard1.6/Dia2Lib.dll" />
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/microsoft.diagnostics.tracing.traceevent/2.0.49/lib/netstandard1.6/OSExtensions.dll" />
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/microsoft.diagnostics.tracing.traceevent/2.0.49/lib/netstandard1.6/TraceReloggerLib.dll" />
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/microsoft.net.test.sdk/16.4.0/build/netcoreapp2.1" />
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/microsoft.testplatform.testhost/16.4.0/build/netcoreapp2.1/x64/testhost.dll" />
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/microsoft.testplatform.testhost/16.4.0/build/netcoreapp2.1/x64/testhost.exe" />
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.15.1/build/netcoreapp2.0/NUnit3.TestAdapter.dll" />
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.15.1/build/netcoreapp2.0/NUnit3.TestAdapter.pdb" />
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.15.1/build/netcoreapp2.0/nunit.engine.api.dll" />
|
||||||
|
<content url="file://$USER_HOME$/.nuget/packages/nunit3testadapter/3.15.1/build/netcoreapp2.0/nunit.engine.dll" />
|
||||||
|
<content url="file://$MODULE_DIR$/../.." />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
27
.vscode/launch.json
vendored
Normal file
27
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||||
|
// Use hover for the description of the existing attributes
|
||||||
|
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": ".NET Core Launch (console)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "build",
|
||||||
|
// If you have changed target frameworks, make sure to update the program path.
|
||||||
|
"program": "${workspaceFolder}/bin/Debug/netcoreapp3.1/Benchmark.dll",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
|
||||||
|
"console": "internalConsole",
|
||||||
|
"stopAtEntry": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": ".NET Core Attach",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "attach",
|
||||||
|
"processId": "${command:pickProcess}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
42
.vscode/tasks.json
vendored
Normal file
42
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"${workspaceFolder}/Benchmark.csproj",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "publish",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"publish",
|
||||||
|
"${workspaceFolder}/Benchmark.csproj",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "watch",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"watch",
|
||||||
|
"run",
|
||||||
|
"${workspaceFolder}/Benchmark.csproj",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
24
Benchmark.csproj
Normal file
24
Benchmark.csproj
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="TestProject1\**" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Remove="TestProject1\**" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="TestProject1\**" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
48
Benchmark.sln
Normal file
48
Benchmark.sln
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.26124.0
|
||||||
|
MinimumVisualStudioVersion = 15.0.26124.0
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmark", "Benchmark.csproj", "{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject1", "TestProject1\TestProject1.csproj", "{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{994B1E75-4E3A-4A11-8363-FFB5FC759A5B}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{C6BD6A51-7394-4CDD-962C-2C39AC2D846C}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
67
Identity.cs
Normal file
67
Identity.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Benchmark
|
||||||
|
{
|
||||||
|
public readonly struct Identity
|
||||||
|
{
|
||||||
|
public Identity(string prefix, int index, int revision)
|
||||||
|
{
|
||||||
|
Prefix = prefix;
|
||||||
|
Index = index;
|
||||||
|
Revision = revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Prefix { get; }
|
||||||
|
public int Index { get; }
|
||||||
|
public int Revision { get; }
|
||||||
|
|
||||||
|
public static bool TryParse(string value, out Identity identity)
|
||||||
|
{
|
||||||
|
identity = default;
|
||||||
|
var position = value.Length;
|
||||||
|
if (!TryGetNumber(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;
|
||||||
|
identity = new Identity(prefix, index, revision);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryGetPrefix(in string identity, ref int lastPosition, out string prefix)
|
||||||
|
{
|
||||||
|
prefix = identity.Remove(lastPosition + 1);
|
||||||
|
if (prefix.Length <= 3) return false;
|
||||||
|
return !prefix.Any(character => character < 'A' || character > 'Z');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryGetNumber(in 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 < '1' || current > '9') break;
|
||||||
|
revision += (current - '0') * IntegerPow(10, start - currentPosition - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exactLength != null && start - (currentPosition + 1) != exactLength) return false;
|
||||||
|
return revision != default;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static int IntegerPow(int x, int y)
|
||||||
|
{
|
||||||
|
if (y == 0) return 1;
|
||||||
|
var result = x;
|
||||||
|
for (var i = 1; i < y; i++)
|
||||||
|
{
|
||||||
|
result *= x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
IdentityParser.cs
Normal file
30
IdentityParser.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
|
||||||
|
namespace Benchmark
|
||||||
|
{
|
||||||
|
[MemoryDiagnoser]
|
||||||
|
public class IdentityParser
|
||||||
|
{
|
||||||
|
private const string TestIdentity = "ABZ0000001-1";
|
||||||
|
private readonly Regex _regex = new Regex(@"^(\w{3,})(\d{7})-(\d+)$", RegexOptions.Compiled);
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public Identity? Parse1()
|
||||||
|
{
|
||||||
|
var match = _regex.Match(TestIdentity);
|
||||||
|
if (!match.Success) return default;
|
||||||
|
var prefix = match.Groups[1].Value;
|
||||||
|
var index = int.Parse(match.Groups[2].Value);
|
||||||
|
var revision = int.Parse(match.Groups[2].Value);
|
||||||
|
return new Identity(prefix, index, revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public Identity? Parse2()
|
||||||
|
{
|
||||||
|
return Identity.TryParse(TestIdentity, out var identity) ? identity : default(Identity?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
Program.cs
Normal file
13
Program.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using BenchmarkDotNet.Running;
|
||||||
|
|
||||||
|
namespace Benchmark
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
//var summary = BenchmarkRunner.Run<TrailingNumberFromString>();
|
||||||
|
var summary = BenchmarkRunner.Run<IdentityParser>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
TestProject1/TestProject1.csproj
Normal file
19
TestProject1/TestProject1.csproj
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="nunit" Version="3.12.0" />
|
||||||
|
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Benchmark.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
82
TestProject1/UnitTest1.cs
Normal file
82
TestProject1/UnitTest1.cs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
using Benchmark;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace TestProject1
|
||||||
|
{
|
||||||
|
public class Tests
|
||||||
|
{
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test3()
|
||||||
|
{
|
||||||
|
var actual = new TrailingNumberFromString().GetTrailingNumberFromString3();
|
||||||
|
Assert.AreEqual(1234, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test4()
|
||||||
|
{
|
||||||
|
var actual = new TrailingNumberFromString().GetTrailingNumberFromString4();
|
||||||
|
Assert.AreEqual(1234, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test5()
|
||||||
|
{
|
||||||
|
var actual = new TrailingNumberFromString().GetTrailingNumberFromString5();
|
||||||
|
Assert.AreEqual(1234, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test6()
|
||||||
|
{
|
||||||
|
var actual = new IdentityParser().Parse1();
|
||||||
|
Assert.AreEqual("ABZ", actual?.Prefix);
|
||||||
|
Assert.AreEqual(1, actual?.Index);
|
||||||
|
Assert.AreEqual(1, actual?.Revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test7()
|
||||||
|
{
|
||||||
|
var actual = new IdentityParser().Parse2();
|
||||||
|
Assert.AreEqual("ABZ", actual?.Prefix);
|
||||||
|
Assert.AreEqual(1, actual?.Index);
|
||||||
|
Assert.AreEqual(1, actual?.Revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test8()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(Identity.TryParse("TOPFTP0000123-12", out var actual));
|
||||||
|
Assert.AreEqual("TOPFTP", actual.Prefix);
|
||||||
|
Assert.AreEqual(123, actual.Index);
|
||||||
|
Assert.AreEqual(12, actual.Revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test9()
|
||||||
|
{
|
||||||
|
Assert.IsTrue(Identity.TryParse("WPR0001023-12", out var actual));
|
||||||
|
Assert.AreEqual("WPR", actual.Prefix);
|
||||||
|
Assert.AreEqual(1023, actual.Index);
|
||||||
|
Assert.AreEqual(12, actual.Revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test10()
|
||||||
|
{
|
||||||
|
Assert.IsFalse(Identity.TryParse("WPR0001023+12", out _));
|
||||||
|
Assert.IsFalse(Identity.TryParse("Peter", out _));
|
||||||
|
Assert.IsFalse(Identity.TryParse("NCL1-1", out _));
|
||||||
|
Assert.IsFalse(Identity.TryParse("NCL0000001-0", out _));
|
||||||
|
Assert.IsFalse(Identity.TryParse("NCL0000000-1", out _));
|
||||||
|
Assert.IsFalse(Identity.TryParse("Nc0000001-1", out _));
|
||||||
|
Assert.IsFalse(Identity.TryParse("0000001-1", out _));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
118
TrailingNumberFromString.cs
Normal file
118
TrailingNumberFromString.cs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
|
||||||
|
namespace Benchmark
|
||||||
|
{
|
||||||
|
[MemoryDiagnoser]
|
||||||
|
public class TrailingNumberFromString
|
||||||
|
{
|
||||||
|
private readonly Regex _regex = new Regex(@"^\d$", RegexOptions.Compiled);
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public int? GetTrailingNumberFromString1()
|
||||||
|
{
|
||||||
|
const string foo = "Test1234";
|
||||||
|
string sValue = null;
|
||||||
|
|
||||||
|
for (var i = foo.Length - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var regex = new Regex(@"^\d$");
|
||||||
|
|
||||||
|
if (regex.IsMatch(foo[i].ToString()))
|
||||||
|
sValue = foo[i] + sValue;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sValue != null)
|
||||||
|
return Convert.ToInt32(sValue);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public int? GetTrailingNumberFromString2()
|
||||||
|
{
|
||||||
|
const string foo = "Test1234";
|
||||||
|
string sValue = null;
|
||||||
|
|
||||||
|
for (var i = foo.Length - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (_regex.IsMatch(foo[i].ToString()))
|
||||||
|
sValue = foo[i] + sValue;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (sValue != null)
|
||||||
|
return Convert.ToInt32(sValue);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public int? GetTrailingNumberFromString3()
|
||||||
|
{
|
||||||
|
const string foo = "Test1234";
|
||||||
|
var result = 0;
|
||||||
|
|
||||||
|
for (var i = foo.Length - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (foo[i] >= 48 && foo[i] <= 58)
|
||||||
|
{
|
||||||
|
var value = foo[i] - 48;
|
||||||
|
result += value * (int) Math.Pow(10, foo.Length - i - 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public int? GetTrailingNumberFromString4()
|
||||||
|
{
|
||||||
|
const string foo = "Test1234";
|
||||||
|
var result = 0;
|
||||||
|
|
||||||
|
for (var i = foo.Length - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (foo[i] >= 48 && foo[i] <= 58)
|
||||||
|
{
|
||||||
|
var value = foo[i] - 48;
|
||||||
|
result += value * IntegerPow(10, foo.Length - i - 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static int IntegerPow(int x, int y)
|
||||||
|
{
|
||||||
|
if (y == 0) return 1;
|
||||||
|
var result = x;
|
||||||
|
for (var i = 1; i < y; i++)
|
||||||
|
{
|
||||||
|
result *= x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public int? GetTrailingNumberFromString5()
|
||||||
|
{
|
||||||
|
const string foo = "Test1234";
|
||||||
|
var regex = new Regex(@"\d+$");
|
||||||
|
var match = regex.Match(foo);
|
||||||
|
return match.Success && int.TryParse(match.Value, out var result) ? result : default(int?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user