Skip to content

Commit 6e3d933

Browse files
committed
Changelog for the big rewrite.
1 parent ebad06f commit 6e3d933

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

Diff for: CHANGELOG.md

+119
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,125 @@ The format is based on [Keep a
66
Changelog](http://keepachangelog.com/en/1.0.0/) and this project
77
adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
88

9+
## [Unreleased]
10+
### Changed
11+
12+
This is a major release with many breaking changes, and is intended to
13+
stabilise the API more than to denote that the rewrite is now
14+
production ready. You should expect future releases with significant
15+
performance improvements as well as additional APIs, but there should
16+
be no further major release with breaking changes in the immediate
17+
future, barring very serious unforeseen issues.
18+
19+
Specifically, you should expect imminent minor releases with
20+
performance improvements for `Vector` and `OrdMap`, for which I have a
21+
number of known optimisations that remain unimplemented.
22+
23+
#### No More `Arc`
24+
25+
All data structures have been reworked to take values of `A: Clone`
26+
instead of `Arc<A>`, meaning that there's less performance overhead
27+
(as well as mental overhead) when using values that clone cheaply. The
28+
performance gain when values are `A: Copy` is a factor of two or more.
29+
It's expected that users should wrap values in `Arc` themselves when
30+
using values which are expensive to clone.
31+
32+
Data structures still use `Arc` internally to reference nodes, but
33+
values are stored directly in the nodes with no further indirection.
34+
This is also good for cache locality.
35+
36+
You can now also use the `no_arc` feature when compiling `im` to use
37+
`Rc` instead of `Arc` if you don't need the data structures to be
38+
`Send` or `Sync`, yielding another ~20% increase in performance.
39+
40+
#### `std::collections` Compatible API
41+
42+
The API has been reworked to align more closely with
43+
`std::collections`, favouring mutable operations by default, so that
44+
operations that were previously suffixed with `_mut` are now the
45+
standard operations, and immutable operations which return a modified
46+
copy have been given different names altogether. In short, all your
47+
code using previous versions of this library will no longer work, and
48+
if it was relying heavily on immutable operations, it's recommended
49+
that you rewrite it to be mutable by preference, but you should
50+
generally be able to make it work again by using the new method names
51+
for the immutable operations.
52+
53+
Here is a list of the most notable changed method names for maps and
54+
sets:
55+
56+
| Previous immutable | Current immutable | Previous mutable | Current mutable |
57+
| --- | --- | --- | --- |
58+
| `insert` | `update` | `insert_mut` | `insert` |
59+
| `remove` | `without` | `remove_mut` | `remove` |
60+
| `pop` | `extract` | `pop_mut` | `remove` |
61+
62+
You should expect to be able to rewrite code using
63+
`std::collections::HashMap` and `std::collections::BTreeMap` with
64+
minimal or no changes using `im::HashMap` and `im::OrdMap`
65+
respectively.
66+
67+
`Vector` has been completely rewritten and has an API that aligns closely with
68+
`std::collections::VecDeque`, with very few immutable equivalents.
69+
It's expected that you should use `Vector::clone()` to take a snapshot
70+
when you need it rather than cause an implicit clone for each
71+
operation. (It's still O(1) and practically instant.)
72+
73+
#### RRB Vector
74+
75+
`Vector` is now implemented as an [RRB
76+
tree](https://infoscience.epfl.ch/record/213452/files/rrbvector.pdf)
77+
with [smart head/tail
78+
chunking](http://gallium.inria.fr/~rainey/chunked_seq.pdf), obsoleting
79+
the previous [Hickey
80+
trie](https://hypirion.com/musings/understanding-persistent-vector-pt-1)
81+
implementation.
82+
83+
RRB trees have generally similar performance characteristics to the
84+
Hickey trie, with the added benefit of having O(log n) splitting and
85+
concatenation.
86+
87+
| Operation | RRB tree | Hickey trie | Vec | VecDeque |
88+
| --- | --- | --- | --- | --- |
89+
| Push front | O(1)* | O(log n) | O(n) | O(1)* |
90+
| Push back | O(1)* | O(log n) | O(1)* | O(1)* |
91+
| Pop front | O(1)* | O(log n) | O(n) | O(1)* |
92+
| Pop back | O(1)* | O(log n) | O(1) | O(1)* |
93+
| Lookup by index | O(log n) | O(log n) | O(1) | O(1) |
94+
| Split | O(log n) | O(log n) | O(n) | O(n) |
95+
| Join | O(log n) | O(n) | O(n) | O(n) |
96+
97+
(Please note that the timings above are for the `im` version of the
98+
Hickey trie, based on the
99+
[Immutable.js](https://facebook.github.io/immutable-js/)
100+
implementation, which performs better than the original Clojure
101+
version on splits and push/pop front, but worse on push/pop back).
102+
103+
The RRB tree is the most generally efficient list like data structure
104+
currently known, to my knowledge, but obviously it does not and cannot
105+
perform as well as a simple `Vec` on certain operations. It makes up
106+
for that by having no operations you need to worry about the
107+
performance complexity of: nothing you can do to an RRB tree is going
108+
to be more expensive than just iterating over it. For larger data
109+
sets, being able to concatenate (and, by extension, insert and remove
110+
at arbitrary locations) several orders of magnitude faster than `Vec`
111+
could also be considered a selling point.
112+
113+
#### No More `CatList` And `ConsList`
114+
115+
`CatList` has been superseded by `Vector`, and `ConsList` was
116+
generally not very useful except in the more peculiar edge cases where
117+
memory consumption matters more than performance, and keeping it in
118+
line with current API changes wasn't practical.
119+
120+
#### No More Funny Words
121+
122+
Though it breaks my heart, words like `cons`, `snoc`, `car`, `cdr` and
123+
`uncons` are no longer used in the `im` API, to facilitiate closer
124+
alignment with `std::collections`. Even the `head`/`tail` pair is
125+
gone, though `head` and `last` remain as aliases for `front` and
126+
`back`.
127+
9128
## [10.2.0] - 2018-04-15
10129
### Added
11130

0 commit comments

Comments
 (0)