Performance issues with linear hashmap
Nobody has claimed this yet.
- Dominant language
- Haskell
- Stars
- 359
- Forks
- 45
- PR merge metrics
- No merged PRs in 30d
Description
The hashmap in Data.HashMap.Mutable.Linear is orders of magnitude slower than Data.HashMap.Lazy for large inputs.
To Reproduce
I implemented the same code with both Data.HashMap.Mutable.Linear and Data.HashMap.Lazy in this gist. On my computer, I get:
$ hyperfine ./lin-mut ./imm
Benchmark #1: ./lin-mut
Time (mean ± σ): 87.6 ms ± 2.0 ms [User: 85.6 ms, System: 2.0 ms]
Range (min … max): 85.1 ms … 94.1 ms 33 runs
Benchmark #2: ./imm
Time (mean ± σ): 9.2 ms ± 0.5 ms [User: 6.7 ms, System: 2.6 ms]
Range (min … max): 8.5 ms … 13.2 ms 251 runs
Here the mutable linear version is 10x slower. Changing the stopping point from 30_000 to 300_000 makes it 100x slower:
$ hyperfine ./lin-mut ./imm
Benchmark #1: ./lin-mut
Time (mean ± σ): 10.156 s ± 0.162 s [User: 10.118 s, System: 0.028 s]
Range (min … max): 10.026 s … 10.509 s 10 runs
Benchmark #2: ./imm
Time (mean ± σ): 90.0 ms ± 1.7 ms [User: 83.5 ms, System: 6.3 ms]
Range (min … max): 88.0 ms … 94.2 ms 31 runs
All programs were compiled with ghc --make -O2 -fllvm <input>.hs -o <output>.
Expected behavior
I would expect the (nominally O(1)) mutable linear hashmap to have better asymptotics than the O(log n) persistent immutable hashmap.
Environment
- OS name + version: Linux 64-bit. I'm not using Stack or Nix.
- Version of the code: GHC HEAD (
92377c27e1a48d0d3776f65c7074dfeb122b46db), linear-base master (69d2d3331673fc0b637767127ca8f5cb1bdb70f7). In case it's relevant, I had to make a few minor changes to theprimitivelibrary to get it to compile with GHC HEAD.
Additional context
I was unable to figure out how to use unordered-containers with the custom-built GHC, so the faster times are built with GHC 8.10.2. Changing to Data.Map.Lazy produces times only slightly slower (20%) than Data.HashMap.Lazy, and is consistent across compiler versions, so I'm not too worried about it.
This feels like a laziness issue -- I haven't looked into the internals of Data.HashMap.Mutable.Linear, so I'm not really sure where it might be coming from.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked reproduction and the Data.HashMap.Mutable.Linear module, then compare its benchmark with Data.HashMap.Lazy using the reported GHC optimization command. Done means identifying and addressing the cause of the mutable linear hashmap's unexpectedly poor scaling, with benchmarks showing behavior consistent with its expected asymptotics.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- haskell
- Domain
- performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100