Skip to content
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
6 changes: 6 additions & 0 deletions src/FastIDs.TypeId/FastIDs.TypeId.sln
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TypeId.Tests", "TypeId.Test
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TypeId.Benchmarks", "TypeId.Benchmarks\TypeId.Benchmarks.csproj", "{6B112FAC-0310-448C-8654-BE41A7FC39CC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TypeId.BenchmarksNuget", "TypeId.BenchmarksNuget\TypeId.BenchmarksNuget.csproj", "{43BB99E6-90DF-4A1E-B539-B2B3AB6F50DF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -24,5 +26,9 @@ Global
{6B112FAC-0310-448C-8654-BE41A7FC39CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B112FAC-0310-448C-8654-BE41A7FC39CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B112FAC-0310-448C-8654-BE41A7FC39CC}.Release|Any CPU.Build.0 = Release|Any CPU
{43BB99E6-90DF-4A1E-B539-B2B3AB6F50DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43BB99E6-90DF-4A1E-B539-B2B3AB6F50DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43BB99E6-90DF-4A1E-B539-B2B3AB6F50DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43BB99E6-90DF-4A1E-B539-B2B3AB6F50DF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,32 @@ public bool SearchValuesLoopInvalid()
return isValid;
}

[Benchmark]
[BenchmarkCategory("Valid")]
public bool SearchValuesFullValid()
{
var isValid = false;
foreach (var id in _validIds)
{
isValid &= !id.AsSpan().ContainsAnyExcept(_searchValues);
}

return isValid;
}

[Benchmark]
[BenchmarkCategory("Invalid")]
public bool SearchValuesFullInvalid()
{
var isValid = false;
foreach (var id in _invalidIds)
{
isValid &= !id.AsSpan().ContainsAnyExcept(_searchValues);
}

return isValid;
}

[Benchmark]
[BenchmarkCategory("Invalid")]
public bool SearchValuesUnrollInvalid()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ namespace FastIDs.TypeId.Benchmarks.LibraryComparison;
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
public class TypeIdComparison
{
[Params(0, 5, 10, 30, 63)]
[Params(0, 5, 15, 63)]
public int PrefixLength;

private string _suffix = "01h455vb4pex5vsknk084sn02q";
private TypeId[] _fastIdTypeIds = Array.Empty<TypeId>();
private TypeIdDecoded[] _fastIdTypeIdsDecoded = Array.Empty<TypeIdDecoded>();
private TcKs.TypeId.TypeId[] _tcKsTypeIds = Array.Empty<TcKs.TypeId.TypeId>();
private global::TypeId.TypeId[] _cbuctokTypeIds = Array.Empty<global::TypeId.TypeId>();
private const string Suffix = "01h455vb4pex5vsknk084sn02q";

private TypeId[] _fastIdTypeIds = [];
private TypeIdDecoded[] _fastIdTypeIdsDecoded = [];
private TcKs.TypeId.TypeId[] _tcKsTypeIds = [];
private global::TypeId.TypeId[] _cbuctokTypeIds = [];
#if NET10_0_OR_GREATER
private TypeSafeId.TypeId<Entity>[] _typeSafeIds = Array.Empty<TypeSafeId.TypeId<Entity>>();
private TypeSafeId.TypeId<Entity>[] _typeSafeIds = [];
#endif

private readonly string _prefixFull;
Expand All @@ -42,25 +42,27 @@ public void Setup()
{
var prefix = _prefixFull[..PrefixLength];
var typeIdStr = PrefixLength > 0
? $"{prefix}_{_suffix}"
: _suffix;
? $"{prefix}_{Suffix}"
: Suffix;

#if NET10_0_OR_GREATER
#pragma warning disable CS0618 // Type or member is obsolete
TypeSafeId.TypeId<Entity>.SetPrefix(prefix);
#pragma warning restore CS0618 // Type or member is obsolete
#endif

_fastIdTypeIds = new[] { TypeId.Parse(typeIdStr), TypeId.Parse(typeIdStr) };
_fastIdTypeIdsDecoded = new[] { TypeId.Parse(typeIdStr).Decode(), TypeId.Parse(typeIdStr).Decode() };
_fastIdTypeIds = [TypeId.Parse(typeIdStr), TypeId.Parse(typeIdStr)];
_fastIdTypeIdsDecoded = [TypeId.Parse(typeIdStr).Decode(), TypeId.Parse(typeIdStr).Decode()];

_tcKsTypeIds = Array.Empty<TcKs.TypeId.TypeId>();
_tcKsTypeIds = [];
if (TcKs.TypeId.TypeId.TryParse(typeIdStr, out var parsed))
{
_tcKsTypeIds = new[] { parsed, parsed };
_tcKsTypeIds = [parsed, parsed];
}

_cbuctokTypeIds = new[] { global::TypeId.TypeId.Parse(typeIdStr), global::TypeId.TypeId.Parse(typeIdStr) };
_cbuctokTypeIds = [global::TypeId.TypeId.Parse(typeIdStr), global::TypeId.TypeId.Parse(typeIdStr)];
#if NET10_0_OR_GREATER
_typeSafeIds = new[] { TypeSafeId.TypeId<Entity>.Parse(typeIdStr), TypeSafeId.TypeId<Entity>.Parse(typeIdStr) };
_typeSafeIds = [TypeSafeId.TypeId<Entity>.Parse(typeIdStr), TypeSafeId.TypeId<Entity>.Parse(typeIdStr)];
#endif
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace FastIDs.TypeId.Benchmarks.LibraryComparison;
[MarkdownExporterAttribute.Default]
public class TypeIdGeneration
{
[Params(0, 5, 10, 30, 63)]
[Params(0, 5, 15, 63)]
public int PrefixLength;

private string _prefix = "";
Expand All @@ -32,7 +32,9 @@ public void Setup()
_prefix = _prefixFull[..PrefixLength];

#if NET10_0_OR_GREATER
#pragma warning disable CS0618 // Type or member is obsolete
TypeSafeId.TypeId<Entity>.SetPrefix(_prefix);
#pragma warning restore CS0618 // Type or member is obsolete
#endif
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace FastIDs.TypeId.Benchmarks.LibraryComparison;
[MarkdownExporterAttribute.GitHub]
public class TypeIdParsing
{
[Params(0, 5, 10, 30, 63)]
[Params(0, 5, 15, 63)]
public int PrefixLength;

private string _typeIdString = "";
Expand Down Expand Up @@ -37,7 +37,9 @@ public void Setup()
_typeIdString = TypeId.FromUuidV7(prefix, _uuidV7).ToString();

#if NET10_0_OR_GREATER
#pragma warning disable CS0618 // Type or member is obsolete
TypeSafeId.TypeId<Entity>.SetPrefix(prefix);
#pragma warning restore CS0618 // Type or member is obsolete
#endif
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace FastIDs.TypeId.Benchmarks.LibraryComparison;
[MarkdownExporterAttribute.Default]
public class TypeIdRetrieveFlow
{
[Params(0, 5, 10, 30, 63)]
[Params(0, 5, 15, 63)]
public int PrefixLength;

private string _typeIdString = "";
Expand Down Expand Up @@ -36,7 +36,9 @@ public void Setup()
_typeIdString = TypeId.FromUuidV7(prefix, _uuidV7).ToString();

#if NET10_0_OR_GREATER
#pragma warning disable CS0618 // Type or member is obsolete
TypeSafeId.TypeId<Entity>.SetPrefix(prefix);
#pragma warning restore CS0618 // Type or member is obsolete
#endif
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace FastIDs.TypeId.Benchmarks.LibraryComparison;
[MarkdownExporterAttribute.Default]
public class TypeIdString
{
[Params(0, 5, 10, 30, 63)]
[Params(0, 5, 15, 63)]
public int PrefixLength;

private readonly string _prefixFull;
Expand Down Expand Up @@ -48,7 +48,9 @@ public void Setup()
#if NET10_0_OR_GREATER
_typeSafeIdTypeId = new TypeSafeId.TypeId<Entity>(_uuidV7);

#pragma warning disable CS0618 // Type or member is obsolete
global::TypeSafeId.TypeId<Entity>.SetPrefix(prefix);
#pragma warning restore CS0618 // Type or member is obsolete
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion src/FastIDs.TypeId/TypeId.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
// .AddJob(Job.Default.WithId("Vector256").WithEnvironmentVariable("DOTNET_EnableAVX512F", "0"))
// .AddJob(Job.Default.WithId("Vector512"));

BenchmarkSwitcher.FromAssembly(Assembly.GetExecutingAssembly()).Run(config: config);
BenchmarkSwitcher.FromAssembly(Assembly.GetExecutingAssembly()).Run(config: config, args: args);
28 changes: 28 additions & 0 deletions src/FastIDs.TypeId/TypeId.BenchmarksNuget/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Reflection;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Running;

var config = DefaultConfig.Instance
.WithOptions(ConfigOptions.JoinSummary)
.HideColumns("Arguments", "RatioSD", "Alloc Ratio")
.AddLogicalGroupRules(BenchmarkLogicalGroupRule.ByMethod);

string[] typeIdNugetVersions =
[
"1.3.0-alpha.0.1",
"1.2.1",
"1.1.0",
"1.0.0"
];

for (var i = 0; i < typeIdNugetVersions.Length; i++)
{
var version = typeIdNugetVersions[i];
config = config.AddJob(Job.Default.WithMsBuildArguments($"/p:SciVersion={version}").WithId(version).WithBaseline(i == 0));
}

BenchmarkSwitcher.FromAssembly(Assembly.GetExecutingAssembly()).Run(config: config, args: args);
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<PropertyGroup>
<!-- Use 9.0.0 as default package version if not specified -->
<SciVersion Condition="'$(SciVersion)' == ''">1.0.0</SciVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
<PackageReference Include="FastIDs.TypeId" Version="$(SciVersion)" />
</ItemGroup>

</Project>
132 changes: 132 additions & 0 deletions src/FastIDs.TypeId/TypeId.BenchmarksNuget/TypeIdBasicOps.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using System.Text;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;

namespace TypeId.BenchmarksNuget;

[MemoryDiagnoser]
[MarkdownExporter]
[MarkdownExporterAttribute.Default]
public class TypeIdBasicOps
{
[Params(0, 15, 63)]
public int TypeLength;

private string _typeIdString = "";
private FastIDs.TypeId.TypeIdDecoded _typeIdDecoded;
private FastIDs.TypeId.TypeId _typeId;
private string _prefix = "";

private readonly string _prefixFull;
private readonly Guid _uuidV7;

public TypeIdBasicOps()
{
var random = new Random(42);
var sb = new StringBuilder(63);
for (var i = 0; i < 63; i++)
{
var letter = (char) random.Next('a', 'z');
sb.Append(letter);
}
_prefixFull = sb.ToString();
_uuidV7 = new Guid("01890a5d-ac96-774b-bcce-b302099a8057");
}

[GlobalSetup]
public void Setup()
{
_prefix = _prefixFull[..TypeLength];
_typeIdDecoded = FastIDs.TypeId.TypeId.FromUuidV7(_prefix, _uuidV7);
_typeId = _typeIdDecoded.Encode();
_typeIdString = _typeId.ToString();
}

[Benchmark]
public FastIDs.TypeId.TypeId Parse()
{
return FastIDs.TypeId.TypeId.Parse(_typeIdString);
}

[Benchmark]
public FastIDs.TypeId.TypeId TryParse()
{
FastIDs.TypeId.TypeId.TryParse(_typeIdString, out var typeId);
return typeId;
}

[Benchmark]
public FastIDs.TypeId.TypeIdDecoded Decode()
{
return _typeId.Decode();
}

[Benchmark]
public FastIDs.TypeId.TypeId Encode()
{
return _typeIdDecoded.Encode();
}

[Benchmark]
public FastIDs.TypeId.TypeIdDecoded Generate()
{
return FastIDs.TypeId.TypeId.New(_prefix);
}

[Benchmark]
public FastIDs.TypeId.TypeIdDecoded GenerateUnsafe()
{
return FastIDs.TypeId.TypeId.New(_prefix, false);
}

[Benchmark]
public string DecodedToString()
{
return _typeIdDecoded.ToString();
}

[Benchmark]
public string EncodedToString()
{
return _typeId.ToString();
}

[Benchmark]
public DateTimeOffset TimestampFromDecoded()
{
return _typeIdDecoded.GetTimestamp();
}

[Benchmark]
public string SuffixFromDecoded()
{
return _typeIdDecoded.GetSuffix();
}

[Benchmark]
public char SuffixSpanFromDecoded()
{
const int suffixLength = 26;
Span<char> buffer = stackalloc char[suffixLength];
var charsWritten = _typeIdDecoded.GetSuffix(buffer);
return buffer[charsWritten - 1];
}

[Benchmark]
public ReadOnlySpan<char> SuffixSpanFromEncoded()
{
return _typeId.Suffix;
}

[Benchmark]
public string TypeFromDecoded()
{
return _typeIdDecoded.Type;
}

[Benchmark]
public ReadOnlySpan<char> TypeFromEncoded()
{
return _typeId.Type;
}
}
Loading