Persistent data structures are, in my opinion, underrated. Not so much for every day programming tasks, but specifically for code that resembles planning/searching.
I'm wondering if there is some inherit flaw in coding some data structures in Node/JS. Maybe this is just another case of the "Node tax"? Things like boxing, floating point number arithmetic, manual pop counts, array copying with bounds checks, etc would all go quite a far way to making for example the Map quite under performant by quite a significant factor especially with large collection sizes and hot loops. Have no idea what the Node runtime does/optimises for example the software version of PopCount encoded in the Immutable.js.
Having written persistent data structures in other lang's that are quite capable (170ns lookup 10,000,000 elements approx to give a rough guide) - yes it is an order slower than unordered hash mutable structures but often still faster than for example the mutable ordered ones I've tested with the advantage of still being immutable. This does benefit some scenarios where you want data sharing/cheap clones of data.
This was something of a worst case scenario (and it was five years ago, so presumably things have gotten better) but it still underscores the need to carefully consider these tools before adopting them. Do they really offer enough (to your application) to be worth the associated costs in readability, performance, etc.
If the goal is to prevent mutation, maybe there are better ways to do that. If the goal is to really accelerate, it's worth testing. (At the very least, Clojure's vectors seem unlikely to provide a benefit if you're working with vectors of len<32.)
Clojure is a language that really puts the "high" in high level. It is quite difficult to trace a Clojure expression back to what will happen on the CPU - and the innovations on things like vector storage are part of that.
It was a bold decision with the potential to cause pain, but Clojure's vectors are great fun to work with. The "novel" basic data structures get out of the way and generally cause more joy than pain. It is part of a fundamental strategy enabling a strongly immutable style which really pays off when it works in concert with the rest of the language.
I just spent the last few days implementing a better version of an "persistent list" data structure (heavily modelled on Clojure's vector) for a new programming language that I'm working on.
I did a quick survey of existing implementations in multiple languages and found all of them lacking. They are either overly complex, slow, or both. Even Clojure's vector, while being simple and very performant, is only usable as a stack, not as a queue, and therefore IMO inadequate as a "generic random-access array-like data structure" (akin to Python's list, i.e. "just use it don't worry about performance").
My version is about as fast as Clojure's vector, while implementing a "deque"-like interface. It's a bit more complex, but still significantly simpler than Scala's vectors (both Scala 2 and Scala 3). Cyclops (a Java-only persistent collection library) is so slow I didn't even bother finishing the benchmarks. I also compared my code to Rust's `im` (way more complex), C++'s `immer` (stack, not deque) and `immutable.js` (slower than ClojureScript).
There are several libraries that implement variations of deque for Clojure, but Clojure also allows transparent use of Java, so when necessary you can just use the Java deque, which I think is highly optimized.
[+] [-] gugagore|4 years ago|reply
Here is one library I've heard of https://immutable-js.com/ . I don't know of others.
[+] [-] throw868788|4 years ago|reply
Having written persistent data structures in other lang's that are quite capable (170ns lookup 10,000,000 elements approx to give a rough guide) - yes it is an order slower than unordered hash mutable structures but often still faster than for example the mutable ordered ones I've tested with the advantage of still being immutable. This does benefit some scenarios where you want data sharing/cheap clones of data.
[+] [-] mschaef|4 years ago|reply
https://github.com/mschaef/react-matchstick/commit/070802b69...
This was something of a worst case scenario (and it was five years ago, so presumably things have gotten better) but it still underscores the need to carefully consider these tools before adopting them. Do they really offer enough (to your application) to be worth the associated costs in readability, performance, etc.
If the goal is to prevent mutation, maybe there are better ways to do that. If the goal is to really accelerate, it's worth testing. (At the very least, Clojure's vectors seem unlikely to provide a benefit if you're working with vectors of len<32.)
[+] [-] panick21_|4 years ago|reply
Mori is the 'original' Clojure data-structures in Java Script.
https://swannodette.github.io/mori/
[+] [-] roenxi|4 years ago|reply
It was a bold decision with the potential to cause pain, but Clojure's vectors are great fun to work with. The "novel" basic data structures get out of the way and generally cause more joy than pain. It is part of a fundamental strategy enabling a strongly immutable style which really pays off when it works in concert with the rest of the language.
[+] [-] tomp|4 years ago|reply
I did a quick survey of existing implementations in multiple languages and found all of them lacking. They are either overly complex, slow, or both. Even Clojure's vector, while being simple and very performant, is only usable as a stack, not as a queue, and therefore IMO inadequate as a "generic random-access array-like data structure" (akin to Python's list, i.e. "just use it don't worry about performance").
My version is about as fast as Clojure's vector, while implementing a "deque"-like interface. It's a bit more complex, but still significantly simpler than Scala's vectors (both Scala 2 and Scala 3). Cyclops (a Java-only persistent collection library) is so slow I didn't even bother finishing the benchmarks. I also compared my code to Rust's `im` (way more complex), C++'s `immer` (stack, not deque) and `immutable.js` (slower than ClojureScript).
I'll clean up the code and post it here.
[+] [-] tomp|4 years ago|reply
https://github.com/tomprimozic/vector
[+] [-] lkrubner|4 years ago|reply
[+] [-] PMunch|4 years ago|reply