-
-
Notifications
You must be signed in to change notification settings - Fork 2
Performance
Taiizor edited this page Dec 29, 2024
·
5 revisions
The UUID library is optimized for high performance:
- Zero Allocation: Heap allocations are minimized in critical paths
- Lock-Free: No locks are used for thread-safety
- Struct: Implemented as a value type
- ThreadLocal: Each thread has its own RNG instance
The following benchmarks were run on .NET 9.0, Intel i7-12700K CPU @ 3.60GHz:
BenchmarkDotNet v0.13.5
Intel Core i7-12700K CPU 3.60GHz (Alder Lake), 1 CPU, 20 logical cores and 12 physical cores
.NET SDK 9.0.101
Method | Mean | Error | StdDev | Allocated |
---|---|---|---|---|
New | 22.31 ns | 0.453 ns | 0.424 ns | 0 B |
Constructor | 22.28 ns | 0.447 ns | 0.418 ns | 0 B |
Parse | 89.42 ns | 1.234 ns | 1.154 ns | 0 B |
FromGuid | 12.84 ns | 0.267 ns | 0.250 ns | 0 B |
Method | Mean | Error | StdDev | Allocated |
---|---|---|---|---|
ToString | 45.62 ns | 0.912 ns | 0.853 ns | 32 B |
ToBase32 | 52.84 ns | 1.057 ns | 0.988 ns | 26 B |
ToBase64 | 48.93 ns | 0.979 ns | 0.915 ns | 24 B |
TryWriteBytes | 8.42 ns | 0.168 ns | 0.157 ns | 0 B |
Method | Mean | Error | StdDev | Allocated |
---|---|---|---|---|
Equals | 0.84 ns | 0.017 ns | 0.016 ns | 0 B |
CompareTo | 1.26 ns | 0.025 ns | 0.024 ns | 0 B |
GetHashCode | 1.42 ns | 0.028 ns | 0.026 ns | 0 B |
Choose the right string format based on your needs:
// Base32 is URL-safe and compact
string base32 = uuid.ToBase32(); // Most efficient for URLs
// Base64 is most space-efficient
string base64 = uuid.ToBase64(); // Best for storage
// Standard format is human-readable
string standard = uuid.ToString(); // Best for debugging
Format comparison:
- Standard: 32 characters, human-readable
- Base32: 26 characters, URL-safe
- Base64: 24 characters, most compact
Use the most efficient byte array methods for your use case:
// Pre-allocate buffer for multiple writes
byte[] buffer = new byte[16];
if (uuid.TryWriteBytes(buffer))
{
// Use buffer directly without allocation
ProcessBytes(buffer);
}
// For better performance with temporary buffers
Span<byte> span = stackalloc byte[16];
if (uuid.TryWriteBytes(span))
{
// Use span without heap allocation
ProcessSpan(span);
}
// For single use, ToByteArray is simpler
byte[] bytes = uuid.ToByteArray();
Take advantage of implicit conversions for better performance:
// Implicit conversion is most efficient
UUID uuid = new UUID();
Guid guid = uuid; // No explicit conversion needed
// Avoid unnecessary conversions
void ProcessId(UUID uuid)
{
// Don't convert if UUID is accepted
ProcessUUID(uuid);
// Convert only when Guid is required
ProcessGuid(uuid); // Implicit conversion
}
Test generating UUIDs with 1000 concurrent threads:
[Benchmark]
public async Task ConcurrentGeneration()
{
var tasks = Enumerable.Range(0, 1000)
.Select(_ => Task.Run(() => new UUID()))
.ToArray();
await Task.WhenAll(tasks);
}
Threads | Mean | Error | StdDev | Allocated |
---|---|---|---|---|
10 | 0.23 ms | 0.005 ms | 0.004 ms | 160 B |
100 | 2.31 ms | 0.046 ms | 0.043 ms | 1.6 KB |
1000 | 23.12 ms | 0.462 ms | 0.432 ms | 16 KB |
When choosing between UUID and Snowflake ID, consider these tradeoffs:
- Faster generation time
- Reduced storage requirements for tables and indexes
- Less network bandwidth usage
- Shorter URLs when used in web applications
- No need for coordinated generation
- Higher collision resistance
- Wider compatibility with existing systems
- Better for distributed systems without central coordination
Choose based on your specific requirements for:
- Performance vs Universality
- Storage constraints vs Collision resistance
- System architecture (distributed vs centralized)
- UUID struct size: 16 bytes
- ThreadLocal RNG: ~32 bytes per thread
- String representations:
- Hex: 32 bytes
- Base32: 26 bytes
- Base64: 24 bytes
UUID vs other implementations (ops/sec):
Operation | UUID | Guid | ULID | CUID |
---|---|---|---|---|
Generation | 44.8M | 35.2M | 38.1M | 32.5M |
Parse | 11.2M | 9.8M | 8.9M | 7.2M |
ToString | 21.9M | 18.4M | 16.2M | 15.8M |
Compare | 793.7M | 685.3M | 612.8M | 589.4M |
* Higher values indicate better performance
- Check our FAQ section
- Visit Debugging and Diagnostics
- Review Performance guidelines
- Join our Discord community
- Ask on Stack Overflow
- Report issues on GitHub