From 51519944ff464d4fdbb9fc4edcc75cc486293a0b Mon Sep 17 00:00:00 2001 From: Justin Willmert Date: Sat, 21 May 2022 10:04:05 -0500 Subject: [PATCH] Implement hash function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Duplicates improvement made to Base's Enums: JuliaLang/julia#30500 **Before:** ```julia julia> @bitflag Flag1 flag1=0 flag2 flag3 flag4 julia> @benchmark hash(flag1) BenchmarkTools.Trial: 10000 samples with 1000 evaluations. Range (min … max): 11.035 ns … 52.801 ns ┊ GC (min … max): 0.00% … 0.00% Time (median): 15.714 ns ┊ GC (median): 0.00% Time (mean ± σ): 16.003 ns ± 1.305 ns ┊ GC (mean ± σ): 0.00% ± 0.00% ▁▃ █▁▄ ▁ ▂▂▂▁▁▁▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▃▃▃▃▃▄▂▃▄██▆███▃▃▂▂▂▂▆▅█▆▆█▅▃▂ ▃ 11 ns Histogram: frequency by time 17.5 ns < Memory estimate: 0 bytes, allocs estimate: 0. ``` **After:** ```julia julia> @benchmark hash(flag1) BenchmarkTools.Trial: 10000 samples with 1000 evaluations. Range (min … max): 1.397 ns … 33.455 ns ┊ GC (min … max): 0.00% … 0.00% Time (median): 4.819 ns ┊ GC (median): 0.00% Time (mean ± σ): 4.907 ns ± 1.042 ns ┊ GC (mean ± σ): 0.00% ± 0.00% ██ ▅▅ ▂▁▁▁▁▂▂▂▁▁▁▁▂▃▂▁▁▁▁▂▂▁▁▁▂▃▃▂▁▁▁▂▂▂▁▁▁▁▂▂▂▁▁▃███▆▁▂▄███▃▁▂▂ ▃ 1.4 ns Histogram: frequency by time 5.66 ns < Memory estimate: 0 bytes, allocs estimate: 0. ``` --- src/BitFlags.jl | 3 +++ test/runtests.jl | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/BitFlags.jl b/src/BitFlags.jl index cfc606d..9c939f5 100644 --- a/src/BitFlags.jl +++ b/src/BitFlags.jl @@ -239,6 +239,9 @@ macro bitflag(T::Union{Symbol,Expr}, syms...) BitFlags.haszero(::Type{$(esc(typename))}) = $(esc(maskzero)) Base.typemin(x::Type{$(esc(typename))}) = $(esc(typename))($lo) Base.typemax(x::Type{$(esc(typename))}) = $(esc(typename))($hi) + let flag_hash = hash($(esc(typename))) + Base.hash(x::$(esc(typename)), h::UInt) = hash(flag_hash, hash(Integer(x), h)) + end let insts = (Any[$(esc(typename))(v) for v in $(values)]...,) Base.instances(::Type{$(esc(typename))}) = insts end diff --git a/test/runtests.jl b/test/runtests.jl index 260092a..51db6df 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -62,6 +62,10 @@ end @test Flag1(7) & flag1a == flag1a @test flag1a < flag1b < flag1c @test flag1a | flag1b < flag1c + + # Hashing + @test Int(flag2a) == Int(flag3a) # same numerical value, but + @test hash(flag2a) != hash(flag3a) # unique hashes as BitFlag #end #@testset "Type properties" begin