using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Diagnostics;
using System.Security.Cryptography;
using Microsoft.EntityFrameworkCore.ValueGeneration;
public class LongGenerator
public static long LastDateTimeTicks = DateTime.UtcNow.Ticks;
public static long Next()
long ticksNow = DateTime.UtcNow.Ticks;
result = Interlocked.Increment(ref LastDateTimeTicks);
while(Interlocked.CompareExchange(ref LastDateTimeTicks, ticksNow, result) != result);
public class SequentialGuidGenerator
private static byte[] ProcessId = new byte[8];
static SequentialGuidGenerator()
using (var cryptoServiceProvider = new RNGCryptoServiceProvider())
cryptoServiceProvider.GetBytes(ProcessId);
public static Guid Next()
var result = new byte[16];
var sequentialTimestamp = BitConverter.GetBytes(LongGenerator.Next());
if (!BitConverter.IsLittleEndian)
Array.Reverse(sequentialTimestamp);
result[0] = ProcessId[0];
result[1] = ProcessId[1];
result[2] = ProcessId[2];
result[3] = ProcessId[3];
result[4] = ProcessId[4];
result[5] = ProcessId[5];
result[6] = ProcessId[6];
result[7] = ProcessId[7];
result[8] = sequentialTimestamp[1];
result[9] = sequentialTimestamp[0];
result[10] = sequentialTimestamp[7];
result[11] = sequentialTimestamp[6];
result[12] = sequentialTimestamp[5];
result[13] = sequentialTimestamp[4];
result[14] = sequentialTimestamp[3];
result[15] = sequentialTimestamp[2];
public static Guid NewGuid()
var result = new byte[16];
var sequentialTimestamp = BitConverter.GetBytes(LongGenerator.Next());
if (!BitConverter.IsLittleEndian)
Array.Reverse(sequentialTimestamp);
using (var cryptoServiceProvider = new RNGCryptoServiceProvider())
cryptoServiceProvider.GetBytes(ProcessId);
result[0] = ProcessId[0];
result[1] = ProcessId[1];
result[2] = ProcessId[2];
result[3] = ProcessId[3];
result[4] = ProcessId[4];
result[5] = ProcessId[5];
result[6] = ProcessId[6];
result[7] = ProcessId[7];
result[8] = sequentialTimestamp[1];
result[9] = sequentialTimestamp[0];
result[10] = sequentialTimestamp[7];
result[11] = sequentialTimestamp[6];
result[12] = sequentialTimestamp[5];
result[13] = sequentialTimestamp[4];
result[14] = sequentialTimestamp[3];
result[15] = sequentialTimestamp[2];
private Stopwatch _stopwatch = new Stopwatch();
_stopwatch = new Stopwatch();
public void Profile(Action method)
_stopwatch = Stopwatch.StartNew();
var result = _stopwatch.Elapsed;
Console.WriteLine(result.TotalMilliseconds.ToString("\n0.000\n"));
public class TestBenchmark
[BenchmarkDotNet.Attributes.Benchmark]
public void SequentialGuidTest1()
var numberOfIterations = 10;
while(numberOfIterations != 0)
Console.WriteLine(SequentialGuidGenerator.Next());
[BenchmarkDotNet.Attributes.Benchmark]
public void SequentialGuidTest2()
var numberOfIterations = 10;
while(numberOfIterations != 0)
Console.WriteLine(SequentialGuidGenerator.NewGuid());
[BenchmarkDotNet.Attributes.Benchmark]
public void SequentialGuidTest3()
var sequentialGuid = new SequentialGuidValueGenerator();
var numberOfIterations = 10;
while(numberOfIterations != 0)
Console.WriteLine(sequentialGuid.Next(null));
public static void Main(string[] args)
var summary = BenchmarkRunner.Run<TestBenchmark>();