-
Notifications
You must be signed in to change notification settings - Fork 149
Benchmarking
Mori now provides an API suitable for benchmarking its persistent data structure from plain JavaScript. Operations like mori.assoc
are variadic and internally dispatch to the correct arity handler function through the length of arguments
, the overheads incurred are very measurable. In ClojureScript removing this overhead is performed statically via the compiler, however this cannot be automated for JavaScript consumers. To eliminate this overhead Mori now supports direct invocation of function arities by exporting a simple direct api.
var m = require("mori"),
h = m.hashMap();
m.assoc(h, "foo", "bar"); // indirect
m.assoc.f3(h, "foo", "bar"); // direct
The convention is simply fN
where N
is some integer representing the arity. Note some functions only have a single defined arity and a fN
direct invocation will not be available.
Calling into Mori still has overheads likely not to be present in pure JavaScript persistent data structure libraries: factory functions copy arguments into an array and wrap in immutable data structure, and critical entry points like nth
and get
invoke a series of invariant checks, type checks, and custom polymorphic dispatch.
Here is a complete example comparing Mori using the direct API and Immutable.js:
var m = require("mori"),
Immutable = require("immutable");
function time(f, iters) {
iters = iters || 1;
for(var i = 0; i < iters; i++) {
var s = new Date();
f();
console.log("Elapsed "+((new Date()).valueOf()-s.valueOf())+"ms");
console.log("----------");
}
}
// ~180ms Node 0.10.35, 2.26ghz 2010 MBP
time(function() {
var hm = m.hashMap();
for(var i = 0 ; i < 100000; i++) {
for(var j = 0; j < 8; j++) {
hm = m.assoc.f3(hm, "foo"+j, j);
}
}
}, 1);
// ~2000ms
time(function() {
var hm = Immutable.Map();
for(var i = 0 ; i < 100000; i++) {
for(var j = 0; j < 8; j++) {
hm = hm.set("foo"+j, j);
}
}
}, 1);
// ~330ms
time(function() {
var v = m.vector();
for(var i = 0 ; i < 1000000; i++) {
v = m.conj.f2(v, i);
}
}, 1);
// ~2500ms
time(function() {
var l = Immutable.List();
for(var i = 0 ; i < 1000000; i++) {
l = l.push(i);
}
}, 1);
// ~80ms
time(function() {
var v = m.mutable.thaw(m.vector());
for(var i = 0 ; i < 1000000; i++) {
v = m.mutable.conj.f2(v, i);
}
v = m.mutable.freeze(v);
}, 1);
// ~500ms
time(function() {
var l = Immutable.List().asMutable();
for(var i = 0 ; i < 1000000; i++) {
l = l.push(i);
}
l.asImmutable();
}, 1);