# Poor time performance on Dict?

**URL:** <https://discourse.julialang.org/t/poor-time-performance-on-dict/9656>\
**Category:** Performance\
**Created:** [March 12, 2018, 4:51am UTC](https://discourse.julialang.org/t/poor-time-performance-on-dict/9656 "2018-03-12T04:51:39Z")\
**Posts on this page:** 1\
**Showing post:** 14

<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:** [March 12, 2018, 2:05pm UTC](https://discourse.julialang.org/t/poor-time-performance-on-dict/9656/14 "2018-03-12T14:05:03Z")

</div>

> [@bkamins](#):
>
> In python `hash(i)=i` so it is very cheap but avoids collisions only for the case you have specified. In Julia hashing is more involved

You can easily use `hash(i)=i` in Julia as well by defining a wrapper type for the keys, and when I do so I find that performance in the original benchmark is increased by almost a factor of 5, which makes it almost 3x faster than Python for me (in Julia 0.6):

```julia
julia> struct FastHashInt{T<:Integer}; i::T; end

julia> Base.:(==)(x::FastHashInt, y::FastHashInt) = x.i == y.i
       Base.hash(x::FastHashInt, h::UInt) = xor(UInt(x.i), h)

julia> function dict_perf()
           n = 10^7
           x = Dict{Int,Int}()
           sizehint!(x, n)
           for i = 1:n
               x[i] = i
           end
           return x
       end
dict_perf (generic function with 1 method)

julia> @time dict_perf(); @time dict_perf(); @time dict_perf();
  1.754449 seconds (1.48 k allocations: 272.081 MiB, 4.54% gc time)
  1.756465 seconds (11 allocations: 272.001 MiB, 4.38% gc time)
  1.715037 seconds (11 allocations: 272.001 MiB, 1.10% gc time)

julia> function dict_perf2()
           n = 10^7
           x = Dict{FastHashInt{Int},Int}()
           sizehint!(x, n)
           for i = 1:n
               x[FastHashInt(i)] = i
           end
           return x
       end
dict_perf2 (generic function with 1 method)

julia> @time dict_perf2(); @time dict_perf2(); @time dict_perf2();
  0.376183 seconds (1.37 k allocations: 272.073 MiB, 5.45% gc time)
  0.355044 seconds (11 allocations: 272.001 MiB, 3.26% gc time)
  0.350325 seconds (11 allocations: 272.001 MiB, 2.91% gc time)

```

The Python 2 version of this takes 1 second on my machine:

```julia
In [1]: def dict_performance():
    dic = dict()
    for i in xrange(10000000):
        dic[i] = i

In [2]: %time dict_performance();
CPU times: user 873 ms, sys: 188 ms, total: 1.06 s
Wall time: 1.06 s

```

(1.13 seconds in Python 3.) _Update:_ In Julia 0.7, I get an additional factor of 2 speedup (0.18sec for `dict_perf2`).

A moral of this story is that in cases where dictionary performance is critical, you might want a custom hashing function optimized for your use-case. The good news is that this is possible in pure Julia code.

---

_[View the full topic](https://discourse.julialang.org/t/poor-time-performance-on-dict/9656)._
