Skip to content

Instantly share code, notes, and snippets.

@xoofx
Created June 16, 2024 05:11
Show Gist options
  • Save xoofx/15faa78e5fcb0b6ba5e1432fc42843b6 to your computer and use it in GitHub Desktop.
Save xoofx/15faa78e5fcb0b6ba5e1432fc42843b6 to your computer and use it in GitHub Desktop.
UUIDv7Fast.cs
// From a discussion on mastodon https://mastodon.social/@antonz@c.im/112620103070756332
// This version:
// * simplifies the setup (an inline array is already a Span)
// * uses BinaryPrimitives.ReverseEndianness to batch writing the long to the buffer
// * uses SkipLocalsInit on the ctor to avoid some zero init
// Should be ~ 15% faster than the revised version with Span
// Anyway most of the time is spent in DateTimeOffset.UtcNow and RandomNumberGenerator.Fill
using System.Buffers.Binary;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
public readonly struct UUIDv7Fast
{
private readonly InteriorStruct _interior;
[SkipLocalsInit]
public UUIDv7Fast()
{
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
Unsafe.As<InteriorStruct, long>(ref _interior) = BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(timestamp << 16) : timestamp << 16;
Span<byte> value = _interior;
RandomNumberGenerator.Fill(value.Slice(6));
// version and variant
value[6] = (byte)((value[6] & 0x0F) | 0x70);
value[8] = (byte)((value[8] & 0x3F) | 0x80);
}
public byte[] GetBytes() => ((ReadOnlySpan<byte>)_interior).ToArray();
public void CopyTo(Span<byte> destination) => ((ReadOnlySpan<byte>)_interior).CopyTo(destination);
public override string ToString() => Convert.ToHexString(_interior);
public override int GetHashCode()
{
HashCode hc = new();
hc.AddBytes(_interior);
return hc.ToHashCode();
}
[InlineArray(16)]
private struct InteriorStruct
{
private byte _element;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment