JuliaServices / AutoHashEquals.jl

A Julia macro to add == and hash() to composite types.
Other
57 stars 12 forks source link

Cache the hash code when requested. #26

Closed gafter closed 1 year ago

gafter commented 1 year ago

In many client scenarios, thee are types for which the generated code would be more efficient if it (1) computed the hash code at construction time and cached it, and (2) compares the hash codes when comparing for equality, to shortcut the potentially more expensive equality comparisons on the elements.

Specifically, code like this

Using AutoHashEquals

@auto_hash_equals_cached struct Q
    x::Int
end

would be translated to something like

struct Q
    x::Int
    _cached_hash::UInt
    Q(x) = new(x, hash(x))
end

@show_structure Base.hash(x::Q) = x._cached_hash
@show_structure Base.hash(x::Q, h::UInt) = hash(x._cached_hash, h)
@show_structure Base.:(==)(a::Q, b::Q) = a._cached_hash == b._cached_hash && isequal(a.x, b.x)
@show_structure Base.show(io::IO, x::Q) = print(io, "Q(", x.x, ")")

(I'm willing to do the work of implementing this.)

gafter commented 1 year ago

The function show shouldn't be defined if the user has already done so.

You cannot specialize a function on a type that hasn't been declared yet.

gafter commented 1 year ago

The implementation of show should correctly handle cyclic data structures in which Q in on the cycle.

gafter commented 1 year ago

The current latest version (not registered yet) supports all this.