# Document / export \`ht\_keyindex()\` from dict.jl?

**URL:** https://discourse.julialang.org/t/document-export-ht-keyindex-from-dict-jl/83738
**Category:** Internals & Design
**Tags:** performance, dictionary
**Created:** [July 4, 2022, 11:16am UTC](https://discourse.julialang.org/t/document-export-ht-keyindex-from-dict-jl/83738 "2022-07-04T11:16:07Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)
#### Post date: [July 4, 2022, 11:16am UTC](https://discourse.julialang.org/t/document-export-ht-keyindex-from-dict-jl/83738/1 "2022-07-04T11:16:07Z")

</div>

I’d like to avoid repeated lookup of the memory address of some key in a dictionary. Consider the following code:

```julia
function delete_if_even!(d::Dict, k)
    if haskey(d, k) && iseven(d[k])
        delete!(d, k)
    else
        d
    end
end

```

Since a dictionary is implemented as a hash table, the hash computation happens 3 times in the above code, in `haskey`, `getindex`, and `delete!`. The repeated computation can be avoid by rewriting the above function as follows, directly using `ht_keyindex()` from `dict.jl`,

```julia
function delete_if_even_fast!(d::Dict, k)
    index = Base.ht_keyindex(d, k)
    @inbounds index >= 0 && iseven(d.vals[index]) ? Base._delete!(d, index) : d # return d if nothing is done
end

```

In fact, a similar functionality is exported by the C++ stdlib `unordered_map`. An iterator for the memory address of a key can be located by calling `find()`, then you can directly delete a key using the iterator by calling `erase()`. In Julia, the iterator of a dictionary is usually only produced by `iterate()` unless you dig into unexported parts of `dict.jl`. Or maybe there’s a more elegant solution to the problem?

---

<div class="post-metadata">

### Author: ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)
#### Post date: [July 4, 2022, 11:27am UTC](https://discourse.julialang.org/t/document-export-ht-keyindex-from-dict-jl/83738/2 "2022-07-04T11:27:08Z")

</div>

Have a look at `Dictionaries.jl`: [GitHub repo](https://github.com/andyferris/Dictionaries.jl), [Announcement post with some discussion](https://discourse.julialang.org/t/ann-dictionaries-jl-improved-productivity-and-performance-of-dictionaries-in-julia/32074).

---

<div class="post-metadata">

### Author: ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)
#### Post date: [July 4, 2022, 2:29pm UTC](https://discourse.julialang.org/t/document-export-ht-keyindex-from-dict-jl/83738/3 "2022-07-04T14:29:30Z")

</div>

Thanks, it looks neat. But for my use case (heavy insertion / deletion element by element rather than broadcast), the base Dict still seems faster according to my very limited testing. It would be nice if a few more methods are exported by dict.jl, so I can improve my existing code with minimal changes, without relying on undocumented internal details.

---

<div class="post-metadata">

### Author: ![Stephen\_Vavasis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephen_vavasis/32/3389_2.png) [@Stephen\_Vavasis](https://discourse.julialang.org/u/Stephen_Vavasis)
#### Post date: [July 5, 2022, 2:01am UTC](https://discourse.julialang.org/t/document-export-ht-keyindex-from-dict-jl/83738/4 "2022-07-05T02:01:52Z")

</div>

This topic has been discussed several times in Julia language issues, and there is an open PR to address it here: [Add modify! function for lookup/update/insert/delete in one go by tkf · Pull Request #33758 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/33758)

---

<div class="post-metadata">

### Author: ![andyferris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andyferris/32/235_2.png) [@andyferris](https://discourse.julialang.org/u/andyferris)
#### Post date: [August 2, 2022, 3:09am UTC](https://discourse.julialang.org/t/document-export-ht-keyindex-from-dict-jl/83738/5 "2022-08-02T03:09:15Z")

</div>

> [@greatpet](#):
>
> for my use case (heavy insertion / deletion element by element rather than broadcast), the base Dict still seems faster according to my very limited testing

Yeah this is correct.

For the die-hards, in Dictionaries.jl there is a module under contrib/HashDictionaries.jl with a dictionary like the one in `Base`. It is slightly faster than `Dict` because I removed the extra code used to support `WeakKeyDict`, and you can use the Dictionaries.jl token interface (and helper functions) with it. The plan is to turn this into `UnorderedDictionary`, export it, and document it as superior for this use case.

---

<div class="post-metadata">

### Author: ![andyferris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andyferris/32/235_2.png) [@andyferris](https://discourse.julialang.org/u/andyferris)
#### Post date: [August 8, 2022, 12:35pm UTC](https://discourse.julialang.org/t/document-export-ht-keyindex-from-dict-jl/83738/6 "2022-08-08T12:35:13Z")

</div>

To follow up on that, the new Dictionaries.jl 0.3.23 has an `UnorderedDictionary` dictionary type (and `UnorderedIndices` set type) for insertion/deletion/lookup heavy workloads. It would be good to know how it performs for people in the wild.
