6 ms·
Efficient Immutable Collections [pdf]
- norswap 9y agoThis is really cool work by Michael, a collection of configurable data structures. Underlying most of them is CHAMP - a compressed hash array map trie. Essentially it's a trie over the hash of the objects inserted in the map. It's compressed using a clever technique that involves bitmaps. A made a toy implementation of it to get a sense of how it works. There are some accompanying notes that you might find useful: https://github.com/norswap/triemap https://github.com/norswap/triemap
- wyager 9y agoCould you expand a bit on the differences between CHAMPs and HAMTs? Most of the info I see about CHAMPs makes them seem very similar, but with a slightly different node structure.
- drawnwren 9y agoFrom the bottom of the Capsule github page [1]: " HAMTs already feature efficient lookup, insert, and delete operations, however due to their tree-based nature their memory footprints and the runtime performance of iteration and equality checking lag behind array-based counterparts. We introduce CHAMP (Compressed Hash-Array Mapped Prefix-tree), an evolutionary improvement over HAMTs. The new design increases the overall performance of immutable sets and maps. Furthermore, its resulting general purpose design increases cache locality and features a canonical representation." 1 - https://github.com/usethesource/capsule https://github.com/usethesource/capsule
- wyager 9y agoThat doesn't answer any of my questions, and they don't have any citation in that block of text. Real details could be in any of the 8 papers linked, or none at all.
- TheRealPomax 9y agoThat doesn't feel like a problem? As a PhD thesis, the cited works should cover the subjects, but there is no requirement for the citations to be direct, or even useful to the general public who want to "learn more" =) If you just want to know the difference between CHAMP and HAMT, then Google gets you that information pretty swiftly. Maybe you were looking for https://blog.acolyer.org/2015/11/27/hamt https://blog.acolyer.org/2015/11/27/hamt which discusses HAMT and then discusses the improvements CHAMP brings to the table.
- vidarh 9y ago> That doesn't feel like a problem? It doesn't make it a bad thesis, but also doesn't answer the questions asked, which is presumably why they were asked.
- TheRealPomax 9y agoI was trying to tactfully suggest that google would have trivially found that answer instead of waiting for someone on HN to deliver the answer on a silver plate =)
- wyager 9y agoI already found that "answer" and it wasn't very good or descriptive, so I was hoping someone on HN could give me an actual high-quality answer. People here often pull through with good, detailed answers.
- drawnwren 9y agoThey increase cache locality and runtime performance of iteration and equality checking. If that answer isn't sufficient, try watching the ~30min Clojure West video on the github page. The speaker seems to be a bit new to public speaking but his talk on the subject was easy to follow and informative for me.
- 9y ago
- norswap 9y agoIt's all in the README above. But basically each node can have up to 32 (2^5) children. Instead of allocating an array of 32 elements in each node, you have a 32-bits bitmap where the nth bit is set only if the corresponding children is present. All the children are "compressed" into a single array. To be able to index a child quickly, it suffices to count the number of bit set below the bit corresponding to the child (something that can be done with some masking and a intrinsic bit count operation that maps to an ASM instruction). This is a bit simplified. In reality each node distinguishes between its children that are actual key-value map entries and those that are nodes. Additionally, entries are not stored in an extra "Entry" object, but instead occupy two slot in the storage array. Nevertheless that is your principle: each node is sparse and only allocates storage for the children that are actually present (at the cost of maintaining two bitmaps: one for children entries and one for children nodes).
- wyager 9y agoI'm pretty sure that's exactly like a HAMT except that HAMTs only use one bitmap. I'm not sure why the CHAMP is referred to as "compressed", then, since HAMTs are compressed using the same bitmap technique with a slightly different node structure.
- loopingoptimism 9y agoIn principle both HAMT and CHAMP compress sparse associative arrays by construction. However, the bitmap encoding of CHAMP results in a better compression for map data structures, enabled by permuting the elements that are stored in the node's array. This is in particular the case when compared to Clojure's PersistentHashMap. Clojure reserves two array slots per entry to either store a) two pointers inline (i.e., key and value tuple), or b) a single reference to a sub-trie in the second slot. At runtime Clojure checks if the first slot is equal to 'null' for distinguishing cases a)/b) and doing the correct type casts at runtime. The thesis visualizes this in chapter 3, page 42.
- gigatexal 9y agoFascinating for sure. I’m looking forward to see what this gets implemented in
- devrandomguy 9y agoClojure devs: 3.5 is the figure you are looking for, and it does look very good, at first glance.
- emsimot 9y agoDid you mean "3.6 Benchmarks: CHAMP versus Clojure’s and Scala’s HAMTs"? "Speedups Compared to Clojure’s Maps: In every runtime measurement CHAMP is better than Clojure. CHAMP improves by a median 72 % for Lookup, 24 % for Insert, and 32 % for Delete. At iteration and equality checking, CHAMP significantly outperforms Clojure. Iteration (Key) improves by a median 83 %, and Iteration (Entry) by 73 %. Further, CHAMP improves on Equality (Distinct) by a median 96 %, and scores several magnitudes better at Equality (Derived). Speedups Compared to Clojure’s Sets: The speedups of CHAMP for sets are similar to maps across the board, with exception of insertion and deletion where it scores even better." Interesting indeed!
- amelius 9y agoNice results, but in the old days, algorithms improved on other algorithms in the big-O sense.
- kristianp 9y agoA lot more low-hanging fruit in the old days.
- anarazel 9y agoRight, which is why nobody ever used qsort. Or, wait. It's been widely used for a long time...
- amelius 9y agoWell, I didn't say "worst case". If qsort only provided a constant ratio time improvement over bubble sort in the average case, then it wouldn't have been so popular.
- deleted 9y ago[deleted]
- deleted 9y ago[deleted]
- hellofunk 9y agoTo anyone wondering why stuff like this matters, it's because the benefits of functional programming reach new heights when coupled with efficient immutable structures. In C++, for example, you can do functional programming in the most basic sense of the word, and it's actually pretty fun. But it can be very expensive because you are not working on efficient data structures that support the mangling and idioms that make FP really shine. There have been interesting efforts to bring structures like this to C++ but nothing mature or known widespread. When people talk about FP, it's about a lot more than what you can do with functions and expressions; it's about making sure that these functional manipulations remain very fast without lots of copying, and that's what is so fascinating about data structure research: how it supports new ways to write programs.
- lgierth 9y agoVery interesting! We've been using HAMTs in IPFS [1] to make huge directories more efficient (think NPM or Wikipedia), and the memory profile has been a pain, so this looks like a welcome improvement. [1] https://github.com/ipfs/specs/issues/32 https://github.com/ipfs/specs/issues/32
- amenghra 9y agoChris Okasaki's work (cited several times in this thesis) is worth reading if you want to learn more about these kinds of data structures. His thesis is here: https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf and parts of it should be easy to grok by every software engineer. Chris also wrote a book on the same topic.
- candu 9y agoYup. Purely Functional Data Structures (thesis as linked, book: https://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504 https://www.amazon.com/Purely-Functional-Structures-Chris-Ok...) is awesome. I especially found some of the tree-based recursive algorithms eye-opening (once you spend the time to wrap your head around them). IMHO required reading if you're doing any heavy FP work.
- myth_drannon 9y agoAnd there is UChicago course that is following some parts of this book and implements it in Elm language https://www.classes.cs.uchicago.edu/archive/2017/spring/22300-1/ https://www.classes.cs.uchicago.edu/archive/2017/spring/2230...
- tome 9y agoOkasaki's work depends crucially on laziness for turning amortized time bounds into per operation time bounds. Is that the case with the linked work too?
- loopingoptimism 9y agoNo, the linked work describes eager data structures that use techniques such as path-copying for persistence. No laziness required.