Skip to content

Instantly share code, notes, and snippets.

@tonsky
Created May 24, 2015 15:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tonsky/020c7269af6564182718 to your computer and use it in GitHub Desktop.
Save tonsky/020c7269af6564182718 to your computer and use it in GitHub Desktop.
Comparing perf and memory of mutable/immutable data structures
<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