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
32 changes: 32 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Benchmark

on: workflow_dispatch

permissions:
contents: read

defaults:
run:
working-directory: Src

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x

- name: Restore dependencies
run: dotnet restore

- name: Build
run: dotnet build --no-restore

- name: Run benchmark (net9.0)
run: dotnet run bench --framework net9.0 --configuration Release
working-directory: Src/UUIDNext.Benchmarks
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ on:
pull_request:
branches: [ "main" ]

permissions:
contents: read

defaults:
run:
working-directory: Src
Expand Down
2 changes: 1 addition & 1 deletion Src/UUIDNext.Benchmarks/UUIDNext.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0;net4.8</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>12</LangVersion>
Expand Down
18 changes: 17 additions & 1 deletion Src/UUIDNext.Benchmarks/UuidBench.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,20 @@ namespace UUIDNext.Benchmarks;
[MemoryDiagnoser(false)]
public class UuidBench
{
private const string ShortUrl = "http://www.example.com";
private static readonly Guid urlNamespaceId = Guid.Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8");

private static readonly string longUrl = $"{ShortUrl}/?token={GetHexString(1024)}";
private static string GetHexString(int stringLength)
{
Random rng = new();
byte[] buffer = new byte[stringLength / 2];
rng.NextBytes(buffer);
return BitConverter.ToString(buffer)
.Replace("-", "")
.ToLower();
}

private static readonly Generator.UuidV8SqlServerGenerator uuidV8Generator = new();
private static readonly Generator.UuidV7FromSpecificDateGenerator uuidV7Generator = new();

Expand All @@ -21,7 +34,10 @@ public class UuidBench
public Guid NewUuidV4() => Uuid.NewRandom();

[Benchmark]
public Guid NewUuidV5() => Uuid.NewNameBased(urlNamespaceId, "http://www.example.com");
public Guid NewUuidV5_short() => Uuid.NewNameBased(urlNamespaceId, ShortUrl);

[Benchmark]
public Guid NewUuidV5_long() => Uuid.NewNameBased(urlNamespaceId, longUrl);

[Benchmark]
public Guid NewUuidV7() => Uuid.NewSequential();
Expand Down
43 changes: 0 additions & 43 deletions Src/UUIDNext.sln

This file was deleted.

6 changes: 6 additions & 0 deletions Src/UUIDNext.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Solution>
<Project Path="UUIDNext.Benchmarks/UUIDNext.Benchmarks.csproj" />
<Project Path="UUIDNext.Cli/UUIDNext.Cli.csproj" />
<Project Path="UUIDNext.Test/UUIDNext.Test.csproj" />
<Project Path="UUIDNext/UUIDNext.csproj" />
</Solution>
34 changes: 15 additions & 19 deletions Src/UUIDNext/Tools/UuidToolkit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,44 +87,40 @@ public static Guid CreateUuidFromName(Guid namespaceId, string name, HashAlgorit
/// </summary>
internal static Guid CreateUuidFromName(Guid namespaceId, string name, HashAlgorithm hashAlgorithm, byte version)
{
const int namespaceBytesCount = 16;
//Convert the name to a canonical sequence of octets (as defined by the standards or conventions of its name space);
var normalizedName = name.Normalize(NormalizationForm.FormC);
var utf8NameByteCount = Encoding.UTF8.GetByteCount(normalizedName);
int bytesToHashCount = namespaceBytesCount + utf8NameByteCount;
#if NETSTANDARD2_0
byte[] utf8NameBytes = new byte[utf8NameByteCount];
Encoding.UTF8.GetBytes(normalizedName, 0, normalizedName.Length, utf8NameBytes, 0);
byte[] bytesToHash = new byte[bytesToHashCount];

//put the name space ID in network byte order.
Span<byte> namespaceBytes = stackalloc byte[16];
//put the namespace ID in network byte order.
Span<byte> namespaceBytes = bytesToHash.AsSpan(0, namespaceBytesCount);
namespaceId.TryWriteBytes(namespaceBytes, bigEndian: true, out _);

//Compute the hash of the name space ID concatenated with the name.
int bytesToHashCount = namespaceBytes.Length + utf8NameBytes.Length;
byte[] bytesToHash = new byte[bytesToHashCount];
namespaceBytes.CopyTo(bytesToHash);
utf8NameBytes.CopyTo(bytesToHash, namespaceBytes.Length);
Encoding.UTF8.GetBytes(normalizedName, 0, normalizedName.Length, bytesToHash, namespaceBytesCount);

//Compute the hash of the namespace ID concatenated with the name.
var hash = hashAlgorithm.ComputeHash(bytesToHash);

return CreateGuidFromBigEndianBytes(hash.AsSpan(0, 16), version);
#else
Span<byte> utf8NameBytes = (utf8NameByteCount > 256) ? new byte[utf8NameByteCount] : stackalloc byte[utf8NameByteCount];
Encoding.UTF8.GetBytes(normalizedName, utf8NameBytes);
const int stackallocMaxSize = 512;
Span<byte> bytesToHash = (utf8NameByteCount > stackallocMaxSize) ? new byte[bytesToHashCount] : stackalloc byte[bytesToHashCount];

//put the name space ID in network byte order.
Span<byte> namespaceBytes = stackalloc byte[16];
//put the namespace ID in network byte order.
Span<byte> namespaceBytes = bytesToHash[..namespaceBytesCount];
namespaceId.TryWriteBytes(namespaceBytes, bigEndian: true, out _);

//Compute the hash of the name space ID concatenated with the name.
int bytesToHashCount = namespaceBytes.Length + utf8NameBytes.Length;
Span<byte> bytesToHash = (utf8NameByteCount > 256) ? new byte[bytesToHashCount] : stackalloc byte[bytesToHashCount];
namespaceBytes.CopyTo(bytesToHash);
utf8NameBytes.CopyTo(bytesToHash[namespaceBytes.Length..]);
Span<byte> utf8NameBytes = bytesToHash[namespaceBytesCount..];
Encoding.UTF8.GetBytes(normalizedName, utf8NameBytes);

//Compute the hash of the namespace ID concatenated with the name.
Span<byte> hash = stackalloc byte[hashAlgorithm.HashSize / 8];
hashAlgorithm.TryComputeHash(bytesToHash, hash, out _);

return CreateGuidFromBigEndianBytes(hash[0..16], version);
return CreateGuidFromBigEndianBytes(hash[..16], version);
#endif
}

Expand Down