Probably Dance
probablydance.com · Personal blog · on HN since 2013
Malte Skarupke writes about C++ performance, hash tables, data structures, and debugging low-level concurrency problems.
What HN saysCommenters call his posts great reads and point to his hash table and min-max heap articles, including graphs that undermine the idea of constant-time lookups.
74HN people shared it
35linked it in comments
84stories submitted
5.5Kstory points
3 months agolast shared
2013people per year2026
Most-shared posts
- 1Fibonacci Hashing: The Optimization That the World Forgot10 people · 561 points · first shared 2018 · 75 comments on HN
- 2I Wrote My Fastest Hashtable9 people · 382 points · first shared 2017 · 116 comments on HN
- 3Measuring mutexes, spinlocks and how bad the Linux scheduler is7 people · 338 points · first shared 2019 · 93 comments on HN
- 4A new fast hash table in response to Google’s new fast hash table6 people · 393 points · first shared 2018 · 115 comments on HN
- 5Functional programming is not popular because it is weird (2016)6 people · 296 points · first shared 2016 · 508 comments on HN
- 6Finding the “second bug” in glibc’s condition variable6 people · 291 points · first shared 2022 · 81 comments on HN
- 7On modern hardware the min-max heap beats a binary heap5 people · 252 points · first shared 2020 · 43 comments on HN
- 8Using TLA+ in the Real World to Understand a Glibc Bug5 people · 180 points · first shared 2020 · 76 comments on HN
- 9C++ Coroutines Do Not Spark Joy4 people · 213 points · first shared 2021 · 250 comments on HN
- 10Writing a Faster Sorting Algorithm4 people · 206 points · first shared 2016 · 33 comments on HN
- 11Beautiful branchless binary search4 people · 34 points · first shared 2023 · 11 comments on HN
- 12Programmers Spend Their Time – Probably Dance4 people · 5 points · first shared 2026 · discussion on HN
- 13Revisiting Knuth's “Premature Optimization” Paper3 people · 206 points · first shared 2025 · 141 comments on HN
- 14Lessons Learned from Shenzhen I/O2 people · 321 points · first shared 2016 · 57 comments on HN
- 15Neural Networks Are Impressively Good at Compression2 people · 244 points · first shared 2016 · 64 comments on HN
What HN people wrote when they linked it
shoo · 2025-09-30
That was a great read, it's not often we get to read thoughtful retrospectives.
Tangent: the author's older posts also contain some gems -- I very much enjoyed this one about heaps: https://probablydance.com/2020/08/31/on-modern-hardware-the-min-max-he…
That post and the discussion in the blog comments were useful when I was interested in speeding up astar pathfinding (30% speedup of the whole search algorithm by replacing binary (2-ary) min heap with a min heap using a 4-ary tree).
fyp · 2019-12-10
Looking at the performance graphs of different hash table implementations is the best way to invalidate the idea of "constant time":
https://probablydance.com/2018/05/28/a-new-fast-hash-table-in-response…
HN submission with related comments: https://news.ycombinator.com/item?id=17177798
robocat · 2022-10-02
That is even more hilariously hand-wavey, given you just got smoked for that.
Fail-safe systems are notoriously hard to design - what is the truth when one system is wrong? How do you detect that a system is giving the wrong answer (737MAX hardware sensor failure, software working exactly as very carefully designed)? Adding complexity decreases reliability unless some very deep voodoo engineering is applied.
I think you are thinking linearly, that two systems with a 1% failure rate could be put together to make a system with 0.01% failure rate. Bzzzzzzt, wrong, instead you could easily end up with a system with a 5% failure rate.
There are many sources of confounding variables: two systems tend to fail in the same complex corner cases, safety systems tend to have common dependencies (Fukushima tidal wave), and adding complexity to systems adds subtle failure modes.
Disclaimer: I would call myself a software engineer, because my definition of engineering is making good compromises. Other “engineering” disciplines very often work on non-safety critical systems, yet they are still called engineers. And these days software underpins most safety critical systems e.g. you depend somewhat that your CAD software or circuit analysis software returns the correct result, even though software usually disclaims all warranties/guarantees. The designers of the space-shuttle made safety compromises, but that was engineering. SpaceX followed a fail-fast approach, and I think software…
azhu · 2019-10-17
I would venture a guess to say that what makes FP or declarative style programming/thinking feel weird is not any great context like the nature of the human brain but rather the lesser one that usually people try to learn it after already having had learned imperative style stuff.
The functionally written recipe from https://probablydance.com/2016/02/27/functional-programming-is-not-pop… may be less helpful if I need to know exactly what steps to take to bake a cake, but it will actually be much more helpful if I want to know what a baked cake is. It isn't quite a fair example because it leverages how humans already know what a baked cake is, what a preheated oven is, etc and the clunkiness of the FP-style recipe is likely more due to that than anything fundamental to FP.
Let's try a different example that better maps to real world application logic. The task is to build a scootybooty.
Imperatively, a scootybooty program is:
- Acquire four wheels and two axels.
- Chop down a tree.
- Plane wood from tree into curved flat shape.
- Attach axels to convex side of planed wood shape.
- Attach wheels to axel.
Declaratively it is:
- A scootybooty is a planed plank of wood with two trucks.
- A planed plank of wood is a flat board.
- A truck is an axel with two wheels.
Now imagine your boss asks you wtf this scootybooty thing is and what it can do. Which program more quickly allows you to answer these questions? My favorite thing about the…
cb321 · 2025-02-11
For a different, perhaps more practical take on small pointers in hash tables, you might find this interesting: https://probablydance.com/2018/05/28/a-new-fast-hash-table-in-response… with contemporaneous discussion at https://news.ycombinator.com/item?id=17176713
charleslmunger · 2024-07-15
People do that, and find very tricky bugs. One person did it by line-by-line translating C code into TLA+, another by representing the state machine in Coq and checking for predicates validating it in the source. But I don't think a visual representation of the state machine would have diagnosed the bugs the formal checkers did.
https://probablydance.com/2020/10/31/using-tla-in-the-real-world-to-un…
https://probablydance.com/2022/09/17/finding-the-second-bug-in-glibcs-…
https://archive.is/sEXqu
bruce343434 · 2024-03-04
More than just a handful of percent[1], but ok
[1] https://probablydance.com/2017/02/26/i-wrote-the-fastest-hashtable/
nickelpro · 2023-09-24
It's exactly what it says, it's a coroutine with its own stack.
A fiber isn't to some degree a stackful coroutine, it is a stackful coroutine.
A stackless coroutine does not have a its own stack, it uses the calling context's stack and therefore can only yield to the calling context from the top-level coroutine function. A stackful coroutine has its own stack, and so can yield to the calling context from anywhere.
As far as how to implement, I always liked Malte Skarupke's blog post on the subject: https://probablydance.com/2013/02/20/handmade-coroutines-for-windows/
usefulcat · 2023-05-11
(Mostly) branchless binary search, ~twice as fast as std::lower_bound:
https://probablydance.com/2023/04/27/beautiful-branchless-binary-searc…
juliusgeo · 2023-04-30
I was inspired by this article[0] to see if I could beat the Python standard library implementation of "bisect_left" using C-extensions.
[0] https://probablydance.com/2023/04/27/beautiful-branchless-binary-searc…
Yoric · 2023-01-16
For context, both C, C++ and Rust have had experimental implementations coroutines for ages.
They're not standardized in C and Rust. And in C++, the only feedback I've seen is https://probablydance.com/2021/10/31/c-coroutines-do-not-spark-joy/, which didn't look very good.
AnssiH · 2022-09-24
Indeed.
But for the record, the author has since found the issue, and in this case it indeed was a bug in the first patch that was inadvertently fixed by a later patch in the series:
https://probablydance.com/2022/09/17/finding-the-second-bug-in-glibcs-…
buildartefact · 2022-09-14
It was in response to this blog post: https://probablydance.com/2019/12/30/measuring-mutexes-spinlocks-and-h…
Basically your standard CAS loop with _mm_pause() to yield.
MauranKilom · 2021-08-19
> some kind of bucket-optimisation (multiple elements per allocation, instead of one element per allocation) should also meet all constraints the standard sets for this type
Pretty sure that makes it impossible to implement merge without pointer/iterator invalidation, which is a constraint imposed by the standard (https://en.cppreference.com/w/cpp/container/unordered_map/merge).
> it would be good if the person I originally responded to came out and defended his POV
See https://probablydance.com/2017/02/26/i-wrote-the-fastest-hashtable/ if you want numbers, or for example this talk by the same author https://www.youtube.com/watch?v=M2fKMP47slQ.
thomasmg · 2021-08-11
I'm sorry! I thought this implementation uses linear probing. Yes this is not an example of linear probing. But it is much closer to linear probing than to cuckoo hashing (I hope we can agree on this). I also found this blog entry interesting: https://probablydance.com/2017/02/26/i-wrote-the-fastest-hashtable/ (of course "fastest" is relative, when it comes to benchmarks)
mratsim · 2021-03-08
Weave is my multithreading library. It's just a recap of what I went through for future reference.
I unfortunately didn't have time to go through:
- compiling glibc from source
- converting my code to C
- trying to reduce multithreaded synchronization code to a minimal example given how non-deterministic any of those bugs are
- do a write-up
That said, it seems like people went through the motions 4 months after me in this bug:
- https://sourceware.org/bugzilla/show_bug.cgi?id=25847 which affects C#, OCaml, Python
Someone also fully reimplemented Glibc condition variable in TLA+ to prove that the glibc code was buggy:
- https://probablydance.com/2020/10/31/using-tla-in-the-real-world-to-un… (at the bottom)
wallstprog · 2020-12-15
For instance, see this recent post about using TLA+ to find a concurrency bug in glibc's implementation of pthreads:
https://probablydance.com/2020/10/31/using-tla-in-the-real-world-to-un…
tehjoker · 2020-09-18
There was this item on HN recently. :)
https://probablydance.com/2016/12/27/i-wrote-a-faster-sorting-algorith…
j780 · 2020-09-11
This is very interesting and reminds me of something I read 4 years ago. I had wondered about data compression related to brain research after I had read this blog: https://probablydance.com/2016/04/30/neural-networks-are-impressively-…
derimagia · 2020-01-06
https://www.realworldtech.com/forum/?threadid=189711 is the original post (what you linked). The quote is from https://probablydance.com/2019/12/30/measuring-mutexes-spinlocks-and-h…
sharken · 2020-01-04
This is pretty much the conclusion in this game related post on spinlocks:
https://probablydance.com/2019/12/30/measuring-mutexes-spinlocks-and-h…
strangenessak · 2019-10-17
> personally I find my brain works very much like a Turing Machine
Exactly this. How baking a cake in FP looks like:
* A cake is a hot cake that has been cooled on a damp tea towel, where a hot cake is a prepared cake that has been baked in a preheated oven for 30 minutes.
* A preheated oven is an oven that has been heated to 175 degrees C.
* A prepared cake is batter that has been poured into prepared pans, where batter is mixture that has chopped walnuts stirred in. Where mixture is butter, white sugar and brown sugar that has been creamed in a large bowl until light and fluffy
Taken from here:
https://probablydance.com/2016/02/27/functional-programming-is-not-pop…
flowerlad · 2019-10-17
I think you can do better than calling something you disagree with “rubbish” because your team didn’t have problems with it.
Here’s an example of people finding functional programming unnatural, maybe you can leverage your experience to explain why he is wrong:
Functional Programming Is Not Popular Because It Is Weird https://probablydance.com/2016/02/27/functional-programming-is-not-pop…
pas · 2019-10-17
Could you elaborate on this a bit? Basically calling a functions form an other is how a step-by-step algorithm would work in FP, no? And pattern match on what comes in, and return an immutable copy.
For example you can put functions in a list, and push a datastructure through them, like a pipeline.
edit: https://probablydance.com/2016/02/27/functional-programming-is-not-pop…
jemfinch · 2019-02-13
Seems to accomplish the same purpose as Fibonacci Hashing[0], but with more steps.
[0] https://probablydance.com/2018/06/16/fibonacci-hashing-the-optimizatio…
palant · 2018-10-24
It should be obvoius that hash table lookups are above O(1) as long as collisions exist. Tweaking the load factor can reduce the probability of collisions, but that's merely a constant factor to the lookup complexity. As to whether O(log(n)) is a good approximation for the average, we can certainly discuss that. It depends a lot on the algorithm, but https://probablydance.com/2017/02/26/i-wrote-the-fastest-hashtable/ shows (first graph) that the reality is typically even above logarithmic for some reason.
Const-me · 2018-10-17
The one I’ve discovered most recently is Fibonacci hashing.
https://probablydance.com/2018/06/16/fibonacci-hashing-the-optimizatio…
uryga · 2018-07-20
Quaternions, in three words: "Rotations in 3D". I like this explanation:
https://probablydance.com/2017/08/05/intuitive-quaternions/