Skip to content

HashHelper

Shmellyorc edited this page Aug 31, 2026 · 4 revisions

HashHelper provides high-performance FNV-1a hashing utilities with caching support for both 32-bit and 64-bit hash values.


Overview

Feature Description
Algorithm FNV-1a (Fowler-Noll-Vo) non-cryptographic hash
Hash Sizes 32-bit and 64-bit variants
Caching Thread-safe caching for frequently accessed strings
Performance Stack allocation for small strings, array pooling for large strings
Enum Support Hash enum values directly
Thread Safety Fully thread-safe

Why FNV-1a?

FNV-1a is a non-cryptographic hash algorithm designed for speed. It produces high-quality hash values suitable for hash tables, dictionaries, and other data structures. It is significantly faster than cryptographic hashes like SHA-256 or MD5.

Use Case Recommended
Dictionary keys
Cache lookups
String identification
Security-sensitive ❌ (use cryptographic hashes)

Methods

Cache32

Gets a cached 32-bit hash for the specified input.

// Hash a string with caching
uint hash = HashHelper.Cache32("Hello World");

// Hash an enum with caching
uint enumHash = HashHelper.Cache32(MyEnum.Value);

// Subsequent calls return the cached value
uint hash2 = HashHelper.Cache32("Hello World");  // Same as hash

Cache64

Gets a cached 64-bit hash for the specified input.

// Hash a string with caching
ulong hash = HashHelper.Cache64("Hello World");

// Hash an enum with caching
ulong enumHash = HashHelper.Cache64(MyEnum.Value);

// Subsequent calls return the cached value
ulong hash2 = HashHelper.Cache64("Hello World");  // Same as hash

Hash32

Computes a 32-bit FNV-1a hash from a string, byte array, or span.

// Hash a string (no caching)
uint hash = HashHelper.Hash32("Hello World");

// Hash a byte array
byte[] data = Encoding.UTF8.GetBytes("Hello World");
uint hash2 = HashHelper.Hash32(data);

// Hash a span
ReadOnlySpan<byte> span = data;
uint hash3 = HashHelper.Hash32(span);

Hash64

Computes a 64-bit FNV-1a hash from a string, byte array, or span.

// Hash a string (no caching)
ulong hash = HashHelper.Hash64("Hello World");

// Hash a byte array
byte[] data = Encoding.UTF8.GetBytes("Hello World");
ulong hash2 = HashHelper.Hash64(data);

// Hash a span
ReadOnlySpan<byte> span = data;
ulong hash3 = HashHelper.Hash64(span);

Examples

String Dictionary Keys

private Dictionary<uint, Texture> _textureCache = new();

public Texture GetTexture(string path)
{
    uint hash = HashHelper.Cache32(path);
    
    if (_textureCache.TryGetValue(hash, out var texture))
        return texture;
    
    texture = AssetManager.Instance.Load<Texture>(path);
    _textureCache[hash] = texture;
    return texture;
}

Enum Caching

public enum EntityType
{
    Player,
    Enemy,
    NPC,
    Item
}

// Cache by enum for fast lookups
private Dictionary<uint, Entity> _entityCache = new();

public Entity GetEntity(EntityType type)
{
    uint hash = HashHelper.Cache32(type);
    
    if (_entityCache.TryGetValue(hash, out var entity))
        return entity;
    
    entity = CreateEntity(type);
    _entityCache[hash] = entity;
    return entity;
}

LDtk Setting Lookups

// In LDtk map loading, settings are stored by hash
var settings = level.Settings;

// Look up a setting by name (converted to hash internally)
if (LDtkSetting.TryGetIntSetting(settings, "Health", out int health))
{
    // Use health value
}

Avoiding Expensive String Comparisons

// Instead of comparing strings directly...
if (entityId == "Player_123")
{
    // ...
}

// Compare hashes for faster lookups
ulong targetHash = HashHelper.Cache64("Player_123");
if (HashHelper.Cache64(entityId) == targetHash)
{
    // ...
}

Performance Notes

Operation Allocation
Hash32 (short string) Stack allocation (no heap)
Hash64 (short string) Stack allocation (no heap)
Hash32 (long string) ArrayPool (minimal GC)
Cache32 (first access) Lazy allocation
Cache32 (cached) No allocation

Thread Safety

HashHelper is fully thread-safe. All methods use concurrent collections or are stateless.

// Safe to use from multiple threads
Parallel.For(0, 1000, i =>
{
    uint hash = HashHelper.Cache32($"Item_{i}");
    // Process hash...
});

Summary

Method Description
Cache32 Cached 32-bit hash of a string or enum
Cache64 Cached 64-bit hash of a string or enum
Hash32 Computed 32-bit hash of a string, byte array, or span
Hash64 Computed 64-bit hash of a string, byte array, or span

Back to Home

Clone this wiki locally