Created
June 16, 2024 05:11
-
-
Save xoofx/15faa78e5fcb0b6ba5e1432fc42843b6 to your computer and use it in GitHub Desktop.
UUIDv7Fast.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// From a discussion on mastodon https://mastodon.social/@[email protected]/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