Skip to content

Commit 0e1e5da

Browse files
committed
big renaming
1 parent f357564 commit 0e1e5da

26 files changed

Lines changed: 477 additions & 472 deletions

README.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ The project is forked from
99
*Persistent* data structure is an immutable structure; the main difference with standard data structures is how you 'write' to them: instead of mutating
1010
the old structure, you create the new, independent, (slightly) modified copy of it. Typical examples of commonly used Persistent structures are String (in Java, Javascript, Python, Ruby) or Python's Tuple or Java's BigDecimal. [(Not only)](http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey) we believe such concept could be beneficial also for other data structures such as Maps, Lists/Vectors, Sets.
1111

12-
var couple = new PersistentMap.fromMap({'father': 'Homer', 'mother': 'Marge'});
12+
var couple = new PMap.fromMap({'father': 'Homer', 'mother': 'Marge'});
1313
// do not (and can not) modify couple anymore
1414
var withChild = couple.assoc('boy', 'Bart');
1515
print(couple); // {mother: Marge, father: Homer}
@@ -28,8 +28,8 @@ got a 'great' idea, that instead of just computing response length he also mutat
2828
Finally, they work as you'd expect. How cool is this:
2929

3030
// deeply persist the structure of Maps and Lists
31-
var a = persist({[1,2]: 'tower', [1,3]: 'water'});
32-
var b = persist({[1,2]: 'tower', [1,3]: 'water'});
31+
PMap a = persist({[1,2]: 'tower', [1,3]: 'water'});
32+
PMap b = persist({[1,2]: 'tower', [1,3]: 'water'});
3333
assert(a==b);
3434
// kids, don't try this with standard List, it ain't going to work
3535
print(a[persist([1, 2])]); // prints 'tower'
@@ -48,21 +48,24 @@ One possible workaround would be to JSONize entries to string and use such strin
4848
Fast copying or equality done right are nice features, but this is not the only selling point here. Having different ways how to copy (shallow, deep) objects or how to compare them (== vs. equals in Java) introduces new complexity. Even if you get used to it, it still takes some part of your mental capabilities and can lead to errors.
4949

5050
### Structure sharing
51-
var map1 = persist({'a': 'something', 'b': bigMap});
52-
var map2 = a.assoc('a', 'something completely different');
51+
PMap map1 = persist({'a': 'something', 'b': bigMap});
52+
PMap map2 = a.assoc('a', 'something completely different');
5353
Suppose you are interested, whether map1['b'] == map2['b']. Thanks to structure sharing, this is O(1) operation, which means it is amazingly fast - no need to traverse through the bigMap. Although it may sound unimportant at the first glance, it is what really enables fast caching of complex functions. Also, this is the reason, why [Om](https://github.com/swannodette/om/) framework is MUCH faster than Facebooks [React](http://facebook.github.io/react/).
5454

5555
## And what is the prize for this all
56-
Short version: size and speed. Although structure sharing makes the whole thing much more effective than naive copy-it-all approach, Persistents still are slower and bigger than their mutable counterparts. Following numbers illustrate, how much less efficient (in terms of speed or memory consumption) are Persistent data structures when benchmarking either on DartVM or Dart2JS on Node:
56+
In the 2.0 release, we optimized memory consumption such that the only penalty for using Persistent
57+
comes at lower speed. Although structure sharing makes the whole thing much more effective than naive
58+
copy-it-all approach, Persistents are still slower than their mutable counterparts (note however, that on
59+
the other hand, some operations runs significantly faster, so its hard to say something conclusive
60+
here). Following numbers illustrate, how much slow are Persistent data structures when benchmarking either on DartVM
61+
or Dart2JS on Node (the numbers are quite independent of the structure size):
5762

58-
* DartVM memory: 2.5
59-
* Dart2JS memory: 6
6063
* DartVM read speed: 2
61-
* DartVM write speed: 2.5
62-
* Dart2JS read speed: 2
63-
* Dart2JS write speed: 4
64+
* DartVM write speed: 12 (5 by using Transients)
65+
* Dart2JS read speed: 3
66+
* Dart2JS write speed: 14 (6 by using Transients)
6467

65-
The good part of the story is, that these numbers are not getting worse, as the Map grows - you get such performance even for Maps with tens of megabytes of data stored within them.
68+
Although the factors are quite big, the whole operation is still very fast and it probably won't be THE bottleneck which would slow down your app.
6669

6770
Some [advanced topics](https://github.com/vacuumlabs/persistent/wiki/Advanced-topics).
6871

benchmark/map_memory/map_memory.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ List data = [];
1616

1717
var creators = {
1818

19-
"persistent": () => new PersistentMap.fromMap(template),
19+
"persistent": () => new PMap.fromMap(template),
2020

2121
"transient": (){
22-
var res = new TransientMap();
22+
var res = new TMap();
2323
template.forEach((k, v) => res.doAssoc(k, v));
2424
return res;
2525
},

benchmark/map_speed/interface_impl.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
part of map_bench;
88

99
class PersistentMapInterface<K, V>
10-
extends EncapsulatingInterface<K, V, PersistentMap<K, V>>{
10+
extends EncapsulatingInterface<K, V, PMap<K, V>>{
1111

1212
PersistentMapInterface(){
13-
this.object = new PersistentMap<K, V>();
13+
this.object = new PMap<K, V>();
1414
}
1515

1616
assoc(K key, V value) =>
@@ -25,10 +25,10 @@ class PersistentMapInterface<K, V>
2525

2626

2727
class TransientMapInterface<K, V>
28-
extends EncapsulatingInterface<K, V, TransientMap<K, V>>{
28+
extends EncapsulatingInterface<K, V, TMap<K, V>>{
2929

3030
TransientMapInterface(){
31-
this.object = new PersistentMap<K, V>().asTransient();
31+
this.object = new PMap<K, V>().asTransient();
3232
}
3333

3434
assoc(K key, V value) =>
@@ -97,7 +97,7 @@ class LinkedListInterface<K, V>
9797
while (it.isCons) {
9898
Cons<Pair<K, V>> cons = it.asCons;
9999
Pair<K, V> elem = cons.elem;
100-
if (elem.first == key) {
100+
if (elem.fst == key) {
101101
builder.add(new Pair<K, V>(key, value));
102102
return builder.build(cons.tail);
103103
}
@@ -113,7 +113,7 @@ class LinkedListInterface<K, V>
113113
while (it.isCons) {
114114
Cons<Pair<K, V>> cons = it.asCons;
115115
Pair<K, V> elem = cons.elem;
116-
if (elem.first == key) return;
116+
if (elem.fst == key) return;
117117
it = cons.tail;
118118
}
119119
}

benchmark/map_speed/makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ run: build/map_speed.js
1616
@echo "Performing several insert, lookup and delete operations on flat maps."
1717
@echo "The number of operations depends on the map size."
1818

19-
# @echo "--------"
20-
# @echo "DartVM:"
21-
# @dart map_speed.dart
19+
@echo "--------"
20+
@echo "DartVM:"
21+
@dart map_speed.dart
2222

2323
@echo "--------"
2424
@echo "NodeJS:"

benchmark/map_speed/map_speed.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,23 @@ part 'interface_impl.dart';
1616

1717
Map interfaces = {
1818
"PersistentMap": () => new PersistentMapInterface(),
19-
//"TransientMap": () => new TransientMapInterface(),
19+
"TransientMap": () => new TransientMapInterface(),
2020
"Map": () => new StandardMapInterface(),
2121
};
2222

23-
int times = 5;
23+
int times = 10;
2424

2525
void main() {
2626
var config = [
2727
{'name': 'Write',
2828
'creator': ((sample, factory) => (new WriteBenchmark(sample, factory))),
29-
// 'sizes': [{10000: 1}],
29+
// 'sizes': [{10000: 1}, ],
3030
'sizes': [{500:60, 1000: 30, 1500: 20, 3000: 10}],
3131
},
3232
{
3333
'name': 'Read',
3434
'creator': ((sample, factory) => (new ReadBenchmark(sample, factory))),
35+
// 'sizes': [{10000: 1}, ],
3536
'sizes': [{500:60, 1000: 30, 1500: 20, 3000: 10}],
3637
}
3738
];

benchmark/vector_memory/vector_memory.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ List data = [];
1515

1616
var creators = {
1717

18-
"persistent": () => new PersistentVector.from(template),
18+
"persistent": () => new PVec.from(template),
1919

2020
"list": () => new List.from(template),
2121
};

benchmark/vector_speed/interface_impl.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
part of vector_speed;
88

99
class PersistentVectorInterface<E>
10-
extends EncapsulatingInterface<E, PersistentVector<E>>{
10+
extends EncapsulatingInterface<E, PVec<E>>{
1111

12-
create() => object = new PersistentVector<E>();
12+
create() => object = new PVec<E>();
1313

1414
push(E value) =>
1515
object = object.push(value);
@@ -25,9 +25,9 @@ class PersistentVectorInterface<E>
2525

2626

2727
class TransientVectorInterface<E>
28-
extends EncapsulatingInterface<E, TransientVector<E>>{
28+
extends EncapsulatingInterface<E, TVec<E>>{
2929

30-
create() => object = new PersistentVector<E>().asTransient();
30+
create() => object = new PVec<E>().asTransient();
3131

3232
push(E value) =>
3333
object.doPush(value);
@@ -39,7 +39,7 @@ class TransientVectorInterface<E>
3939
pop() => object.doPop();
4040

4141
_copy(){
42-
return new PersistentVector.from(object).asTransient();
42+
return new PVec.from(object).asTransient();
4343
}
4444
}
4545

example/overall_example.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ library overall_example;
99
import 'package:vacuum_persistent/persistent.dart';
1010

1111
example(){
12-
var couple = new PersistentMap.fromMap({'father': 'Homer', 'mother': 'Marge'});
12+
var couple = new PMap.fromMap({'father': 'Homer', 'mother': 'Marge'});
1313
var withChild = couple.assoc('boy', 'Bart');
1414
print(couple); // {mother: Marge, father: Homer}
1515
print(withChild); // {boy: Bart, mother: Marge, father: Homer}
@@ -28,8 +28,8 @@ main() {
2828

2929
// Persistency:
3030

31-
final map1 = new PersistentMap.fromMap({"a":1, "b":2});
32-
final map2 = new PersistentMap.fromMap({"b":3, "c":4});
31+
final map1 = new PMap.fromMap({"a":1, "b":2});
32+
final map2 = new PMap.fromMap({"b":3, "c":4});
3333

3434
print(map1["a"]); // 1
3535
print(map1.get("b")); // 2
@@ -48,7 +48,7 @@ main() {
4848

4949
// Transiency:
5050

51-
final vector1 = new PersistentVector.from(["x", "y"]);
51+
final vector1 = new PVec.from(["x", "y"]);
5252

5353
print(vector1.push("z")); // (x, y, z)
5454
print(vector1.push("q")); // (x, y, q)

example/persistent_map_example.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ library map_example;
88
import 'package:vacuum_persistent/persistent.dart';
99

1010
main() {
11-
final emptyMap = new PersistentMap<String,int>();
11+
final emptyMap = new PMap<String,int>();
1212
final m1 = emptyMap.assoc('a', 1).assoc('b', 2);
13-
final m2 = new PersistentMap<String,int>.fromMap({'a': 3, 'c': 4});
13+
final m2 = new PMap<String,int>.fromMap({'a': 3, 'c': 4});
1414

1515
print(m1); // {a: 1, b: 2}
1616
print(m2); // {c: 4, a: 3}

lib/src/cursor.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ part of persistent;
88

99
class Cursor {
1010
final Reference _ref;
11-
final PersistentVector _path;
11+
final PVec _path;
1212

1313
Cursor(Reference this._ref, Iterable path) :
14-
_path = (path is PersistentVector)? path: new PersistentVector.from(path);
14+
_path = (path is PVec)? path: new PVec.from(path);
1515

16-
Cursor operator[](val) => new Cursor(_ref, conj(_path, val) as PersistentVector);
16+
Cursor operator[](val) => new Cursor(_ref, conj(_path, val) as PVec);
1717

1818
deref([notFound = _none]) => getIn(_ref.deref(), _path, notFound);
1919

0 commit comments

Comments
 (0)