# Dictionary with custom hash function

**URL:** <https://discourse.julialang.org/t/dictionary-with-custom-hash-function/49168>\
**Category:** General Usage\
**Tags:** question, dictionary, hash\
**Created:** [October 28, 2020, 9:50am UTC](https://discourse.julialang.org/t/dictionary-with-custom-hash-function/49168 "2020-10-28T09:50:54Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![tisztamo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tisztamo/32/16200_2.png) [@tisztamo](https://discourse.julialang.org/u/tisztamo)\
**Post date:** [October 28, 2020, 9:50am UTC](https://discourse.julialang.org/t/dictionary-with-custom-hash-function/49168/1 "2020-10-28T09:50:54Z")

</div>

In a tight loop (50-100ns/cycle) I am using a dict filled with randomly generated `UInt64` keys.

I think that they could be used directly in a hashmap, without hashing, so I am looking for a hashmap with a custom (here the identity) hash function.

I hope to gain 2.5ns per cycle:

```julia
julia> @btime hash(i) setup=(i=rand(UInt64))
  2.500 ns (0 allocations: 0 bytes)

```

I was not able to quickly find a package that allows that. Is there any?

---

<div class="post-metadata">

**Author:** ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)\
**Post date:** [October 28, 2020, 10:32am UTC](https://discourse.julialang.org/t/dictionary-with-custom-hash-function/49168/2 "2020-10-28T10:32:25Z")

</div>

It takes only a patch of few lines to allow Base’s `Dict` to handle that, here is a [POC](https://github.com/JuliaLang/julia/pull/37964), where you’re welcome to comment 🙂  
I don’t know of an package doing that, but if this PR isn’t merged soon enough, I will package it up.

---

<div class="post-metadata">

**Author:** ![tisztamo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tisztamo/32/16200_2.png) [@tisztamo](https://discourse.julialang.org/u/tisztamo)\
**Post date:** [October 28, 2020, 11:00am UTC](https://discourse.julialang.org/t/dictionary-with-custom-hash-function/49168/3 "2020-10-28T11:00:23Z")

</div>

Thanks, it would be great to have that in Base!

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [October 28, 2020, 12:04pm UTC](https://discourse.julialang.org/t/dictionary-with-custom-hash-function/49168/4 "2020-10-28T12:04:39Z")

</div>

> [@tisztamo](#):
>
> I was not able to quickly find a package that allows that. Is there any?

Just wrap your keys in a new type:

```julia
struct MyKey
    val::UInt
end
Base.hash(a::MyKey, h::UInt) = xor(a.val, h)
Base.(==)(a::MyKey, b::MyKey) = a.val == b.val

```

---

<div class="post-metadata">

**Author:** ![tisztamo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tisztamo/32/16200_2.png) [@tisztamo](https://discourse.julialang.org/u/tisztamo)\
**Post date:** [October 28, 2020, 2:34pm UTC](https://discourse.julialang.org/t/dictionary-with-custom-hash-function/49168/5 "2020-10-28T14:34:42Z")

</div>

Thank you, it works!

I mistakenly thought this will have a performance impact, that’s why I asked for a solution here, but now I have learned to better embrace immutable structs!

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [October 28, 2020, 2:40pm UTC](https://discourse.julialang.org/t/dictionary-with-custom-hash-function/49168/6 "2020-10-28T14:40:19Z")

</div>

There’s a reason one of Julia’s unofficial mottos is “don’t pay for what you use”

---

<div class="post-metadata">

**Author:** ![lewis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lewis/32/5217_2.png) [@lewis](https://discourse.julialang.org/u/lewis)\
**Post date:** [December 30, 2021, 7:45am UTC](https://discourse.julialang.org/t/dictionary-with-custom-hash-function/49168/7 "2021-12-30T07:45:22Z")

</div>

I am sorry. This is missing a lot of steps for me:

How would the dict be defined?

```julia
mydict = Dict{MyKey, String}()
akey = MyKey(10)
mydict[akey] = "foo"

```

This seems restrictive. Key values need to be integers to convert to UInt. It’s actually slower than a normal dictionary.

I am looking for a simple and faster hashing algorithm for very small dicts (4-10 entries) that are accessed in a very lot loop. The values for each entry will never be changed–this is basically a lookup table. However, my lookup table is actually a dict of dicts. LittleDict proved to be slower than normal dict when nested.

Thanks.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [November 23, 2023, 1:37pm UTC](https://discourse.julialang.org/t/dictionary-with-custom-hash-function/49168/8 "2023-11-23T13:37:18Z")

</div>

3 posts were split to a new topic: [Trouble defining hash/isequal for an interval type](https://discourse.julialang.org/t/trouble-defining-hash-isequal-for-an-interval-type/106629)
