diff --git a/README.md b/README.md
index f697b20..b96e7a1 100644
--- a/README.md
+++ b/README.md
@@ -72,28 +72,49 @@ Alternatively, there is a `ToStringIdentifier()` extension method available whic
## Performance
-We've benchmarked FlakeId on .NET 5 against [MassTransit's NewId](https://github.com/phatboyg/NewId) library, and [IdGen](https://github.com/RobThree/IdGen) both libraries are widely used. It is worth noting that NewId generates 128-bit integers.
+We've benchmarked FlakeId on .NET 8 against [MassTransit's NewId](https://github.com/phatboyg/NewId) library, and [IdGen](https://github.com/RobThree/IdGen) both libraries are widely used. It is worth noting that NewId generates 128-bit integers.
We've also included `Guid.NewGuid` as a baseline benchmark, as it is very well optimized, and arguably the most widely used identifier generator in .NET.
```
-BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
-Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
-.NET Core SDK=5.0.201
- [Host] : .NET Core 5.0.4 (CoreCLR 5.0.421.11614, CoreFX 5.0.421.11614), X64 RyuJIT
- DefaultJob : .NET Core 5.0.4 (CoreCLR 5.0.421.11614, CoreFX 5.0.421.11614), X64 RyuJIT
-
-
-| Method | Mean | Error | StdDev | Code Size |
-|--------------- |------------:|-----------:|-----------:|----------:|
-| Single_FlakeId | 30.44 ns | 0.091 ns | 0.080 ns | 254 B |
-| Single_Guid | 59.47 ns | 0.681 ns | 0.637 ns | 111 B |
-| Single_NewId | 75.27 ns | 0.323 ns | 0.270 ns | 40 B |
-| Single_IdGen | 2,445.98 ns | 176.372 ns | 520.036 ns | 687 B |
+BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.3155/23H2/2023Update/SunValley3)
+AMD Ryzen 5 5600X, 1 CPU, 12 logical and 6 physical cores
+.NET SDK 8.0.201
+ [Host] : .NET 8.0.2 (8.0.224.6711), X64 RyuJIT AVX2
+ DefaultJob : .NET 8.0.2 (8.0.224.6711), X64 RyuJIT AVX2
+
+
+| Method | Mean | Error | StdDev | Code Size |
+|--------------- |------------:|----------:|-----------:|----------:|
+| Single_FlakeId | 26.48 ns | 0.020 ns | 0.019 ns | 358 B |
+| Single_Guid | 41.85 ns | 0.481 ns | 0.450 ns | 245 B |
+| Single_NewId | 31.83 ns | 0.013 ns | 0.012 ns | 303 B |
+| Single_IdGen | 3,473.96 ns | 69.295 ns | 168.673 ns | 671 B |
```
In this benchmark, IdGen was configured to `SpinWait` in the event multiple IDs were generated in the same instant. It spent most of its time in a spinlock.
+Below are the benchmark results for FlakeId running on multiple runtimes.
+
+```
+BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.3155/23H2/2023Update/SunValley3)
+AMD Ryzen 5 5600X, 1 CPU, 12 logical and 6 physical cores
+.NET SDK 8.0.201
+ [Host] : .NET 8.0.2 (8.0.224.6711), X64 RyuJIT AVX2
+ .NET 5.0 : .NET 5.0.17 (5.0.1722.21314), X64 RyuJIT AVX2
+ .NET 6.0 : .NET 6.0.27 (6.0.2724.6912), X64 RyuJIT AVX2
+ .NET 7.0 : .NET 7.0.16 (7.0.1624.6629), X64 RyuJIT AVX2
+ .NET 8.0 : .NET 8.0.2 (8.0.224.6711), X64 RyuJIT AVX2
+
+
+| Method | Job | Runtime | Mean | Error | StdDev | Code Size |
+|--------------- |--------- |--------- |---------:|---------:|---------:|----------:|
+| Single_FlakeId | .NET 5.0 | .NET 5.0 | 27.85 ns | 0.111 ns | 0.103 ns | 254 B |
+| Single_FlakeId | .NET 6.0 | .NET 6.0 | 26.37 ns | 0.056 ns | 0.053 ns | 215 B |
+| Single_FlakeId | .NET 7.0 | .NET 7.0 | 26.72 ns | 0.211 ns | 0.176 ns | 209 B |
+| Single_FlakeId | .NET 8.0 | .NET 8.0 | 26.56 ns | 0.085 ns | 0.071 ns | 358 B |
+```
+
## Issues
If you have an issue with FlakeId, please open an issue and describe your problem as accurately as you can.
diff --git a/src/FlakeId.Benchmarks/FlakeId.Benchmarks.csproj b/src/FlakeId.Benchmarks/FlakeId.Benchmarks.csproj
index 36688d0..166471d 100644
--- a/src/FlakeId.Benchmarks/FlakeId.Benchmarks.csproj
+++ b/src/FlakeId.Benchmarks/FlakeId.Benchmarks.csproj
@@ -2,14 +2,14 @@
Exe
- net8.0
+ net8.0;net7.0;net6.0;net5.0
-
-
-
-
+
+
+
+
diff --git a/src/FlakeId.Benchmarks/FlakeIdMultipleRuntimesBenchmarks.cs b/src/FlakeId.Benchmarks/FlakeIdMultipleRuntimesBenchmarks.cs
new file mode 100644
index 0000000..08412c7
--- /dev/null
+++ b/src/FlakeId.Benchmarks/FlakeIdMultipleRuntimesBenchmarks.cs
@@ -0,0 +1,21 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Diagnostics.Windows.Configs;
+using BenchmarkDotNet.Jobs;
+
+namespace FlakeId.Benchmarks
+{
+ [SimpleJob(RuntimeMoniker.Net50)]
+ [SimpleJob(RuntimeMoniker.Net60)]
+ [SimpleJob(RuntimeMoniker.Net70)]
+ [SimpleJob(RuntimeMoniker.Net80)]
+ [DisassemblyDiagnoser]
+ [InliningDiagnoser(true, null)]
+ public class FlakeIdMultipleRuntimesBenchmarks
+ {
+ [Benchmark]
+ public void Single_FlakeId()
+ {
+ Id.Create();
+ }
+ }
+}
diff --git a/src/FlakeId.Benchmarks/IdCreationBenchmarks.cs b/src/FlakeId.Benchmarks/IdCreationBenchmarks.cs
new file mode 100644
index 0000000..a423d69
--- /dev/null
+++ b/src/FlakeId.Benchmarks/IdCreationBenchmarks.cs
@@ -0,0 +1,40 @@
+using System;
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Diagnostics.Windows.Configs;
+using IdGen;
+using MassTransit;
+
+namespace FlakeId.Benchmarks
+{
+ [DisassemblyDiagnoser]
+ [InliningDiagnoser(true, null)]
+ public class IdCreationBenchmarks
+ {
+ private static readonly IdGenerator s_idGenerator = new IdGenerator(10,
+ new IdGeneratorOptions(sequenceOverflowStrategy: SequenceOverflowStrategy.SpinWait));
+
+ [Benchmark]
+ public void Single_FlakeId()
+ {
+ Id.Create();
+ }
+
+ [Benchmark]
+ public void Single_Guid()
+ {
+ Guid.NewGuid();
+ }
+
+ [Benchmark]
+ public void Single_NewId()
+ {
+ NewId.Next();
+ }
+
+ [Benchmark]
+ public void Single_IdGen()
+ {
+ s_idGenerator.CreateId();
+ }
+ }
+}
diff --git a/src/FlakeId.Benchmarks/Program.cs b/src/FlakeId.Benchmarks/Program.cs
index a74850b..aa1dc9f 100644
--- a/src/FlakeId.Benchmarks/Program.cs
+++ b/src/FlakeId.Benchmarks/Program.cs
@@ -1,9 +1,4 @@
-using System;
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Diagnostics.Windows.Configs;
-using BenchmarkDotNet.Running;
-using IdGen;
-using MassTransit;
+using BenchmarkDotNet.Running;
namespace FlakeId.Benchmarks
{
@@ -12,38 +7,7 @@ internal class Program
private static void Main(string[] args)
{
BenchmarkRunner.Run();
- }
- }
-
- [DisassemblyDiagnoser]
- [InliningDiagnoser(true, null)]
- public class IdCreationBenchmarks
- {
- private static readonly IdGenerator s_idGenerator = new IdGenerator(10,
- new IdGeneratorOptions(sequenceOverflowStrategy: SequenceOverflowStrategy.SpinWait));
-
- [Benchmark]
- public void Single_FlakeId()
- {
- Id.Create();
- }
-
- [Benchmark]
- public void Single_Guid()
- {
- Guid.NewGuid();
- }
-
- [Benchmark]
- public void Single_NewId()
- {
- NewId.Next();
- }
-
- [Benchmark]
- public void Single_IdGen()
- {
- s_idGenerator.CreateId();
+ BenchmarkRunner.Run();
}
}
}