Created
May 24, 2015 15:02
-
-
Save tonsky/020c7269af6564182718 to your computer and use it in GitHub Desktop.
Comparing perf and memory of mutable/immutable data structures
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.7.3/immutable.min.js"></script> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mori/0.3.2/mori.js"></script> | |
<script type="text/javascript"> | |
var hex_chars = "0123456789abcdef"; | |
function rand_int(max) { | |
return Math.floor(Math.random() * max); | |
} | |
function rand_nth(coll) { | |
return coll[rand_int(coll.length)]; | |
} | |
function rand_string(len, chars) { | |
var chars = hex_chars; | |
var res = ''; | |
for(var i=0; i<len; ++i) { | |
res += rand_nth(hex_chars); | |
} | |
return res; | |
} | |
function rand_uuid(len) { | |
return rand_string(8) + "-" + | |
rand_string(4) + "-" + | |
rand_string(4) + "-" + | |
rand_string(4) + "-" + | |
rand_string(12); | |
} | |
function rand_color() { | |
return "#" + rand_string(6); | |
} | |
// Mutable version | |
function rand_figure() { | |
return { | |
id: rand_uuid(), | |
x: rand_int(10000), | |
y: rand_int(10000), | |
width: rand_int(1000), | |
height: rand_int(1000), | |
user: rand_uuid(), | |
created: new Date(rand_int(1500000000000)), | |
stroke: rand_color(), | |
fill: rand_color(), | |
stroke_width: rand_int(10), | |
opacity: rand_int(100) | |
}; | |
} | |
function run_mut(n) { | |
var history = [[]]; | |
for (var i=0; i<n; ++i) { | |
var last_scene = history[history.length-1]; | |
var new_scene = last_scene.slice(0); | |
new_scene.push(rand_figure()); | |
history.push(new_scene); | |
} | |
return history; | |
} | |
// Immutable version | |
function rand_figure_i() { | |
return Immutable.Map({ | |
id: rand_uuid(), | |
x: rand_int(10000), | |
y: rand_int(10000), | |
width: rand_int(1000), | |
height: rand_int(1000), | |
user: rand_uuid(), | |
created: new Date(rand_int(1500000000000)), | |
stroke: rand_color(), | |
fill: rand_color(), | |
stroke_width: rand_int(10), | |
opacity: rand_int(100) | |
}); | |
} | |
function run_imm(n) { | |
var history = Immutable.List.of(Immutable.List()); | |
for (var i=0; i<n; ++i) { | |
var last_scene = history.get(history.count() - 1); | |
var new_scene = last_scene.push(rand_figure_i()); | |
history = history.push(new_scene); | |
} | |
return history; | |
} | |
// Mori | |
function rand_figure_mori() { | |
return mori.hashMap( | |
"id", rand_uuid(), | |
"x", rand_int(10000), | |
"y", rand_int(10000), | |
"width", rand_int(1000), | |
"height", rand_int(1000), | |
"user", rand_uuid(), | |
"created", new Date(rand_int(1500000000000)), | |
"stroke", rand_color(), | |
"fill", rand_color(), | |
"stroke_width", rand_int(10), | |
"opacity", rand_int(100) | |
); | |
} | |
function run_mori(n) { | |
var history = mori.vector(mori.vector()); | |
for (var i=0; i<n; ++i) { | |
var last_scene = mori.nth(history, mori.count(history) - 1); | |
var new_scene = mori.conj(last_scene, rand_figure_mori()); | |
history = mori.conj(history, new_scene); | |
} | |
return history; | |
} | |
// Run test on page load | |
function round(x) { return x.toFixed(0); } | |
function median(arr) { return arr.slice(0).sort()[Math.floor(arr.length/2)]; } | |
function measure(id, long_id, times, fn, args) { | |
console.timeStamp(id); | |
fn.apply(null, args); // warmup | |
var t0 = performance.now(), min, max, runs = []; | |
for (var i = 0; i<times; ++i) { | |
var t1 = performance.now(); | |
fn.apply(null, args); | |
var dt1 = performance.now() - t1; | |
if (!min || dt1 < min) | |
min = dt1; | |
if (!max || dt1 > max) | |
max = dt1; | |
runs.push(dt1); | |
} | |
var dt0 = performance.now() - t0; | |
console.log(long_id, | |
"total:", round(dt0), "ms ", | |
"min:", round(min), "ms ", | |
"avg:", round(dt0 / times), "ms ", | |
"median:", round(median(runs)), "ms ", | |
"max:", round(max), "ms "); | |
} | |
var runs = 40, | |
size = 2000; | |
console.log(runs + " runs, " + size + " history size"); | |
measure("js", "javascript ", runs, run_mut, [size]); | |
measure("im", "immutable.js", runs, run_imm, [size]); | |
measure("mr", "mori.js ", runs, run_mori, [size]); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment