Description
Record is currently implemented with a Map. But because it has a fixed size, and because the keys are always strings, it's possible to use a much simpler and faster implementation.
Each Record would have two properties, _keys
and _values
. _keys
is a mutable JavaScript object mapping string keys to indexes, and _values
is a mutable JavaScript array that contains the actual values.
To lookup a key in the Record, you first look it up in _keys
which gives you an index, and then you lookup that index in _values
.
To set a key in a Record, you first look it up in _keys
, which gives you an index. You then make a copy of the _values
array, mutate the index to be the new value, then return a new Record with the new _values
array.
There are a few reasons this is fast:
- You don't need to mutate or copy
_keys
at all: you can simply pass it as-is to the new Record, because it never changes. - Copying an array is super fast in JavaScript, because of various VM optimizations.
- Looking up a string key in a JavaScript object is faster than doing the equivalent lookup in a Map, and you get to take advantage of the various VM optimizations for objects.
I have implemented this technique in my library, and you can find the benchmarks here:
https://github.com/Pauan/Immutable/blob/javascript/benchmarks/Record/2015-01-16
Getting is always super fast. Setting is fast until you reach around 1,000 keys or so, and it's extremely rare to have Records with 1,000+ keys in them, so that isn't a problem.