Created
May 30, 2016 21:20
-
-
Save Zambonilli/5ba68c5a85ec8fbdc8ded8c1f062a012 to your computer and use it in GitHub Desktop.
object join performance in node.js
This file contains 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
'use strict' | |
var Measured = require('measured'); | |
var Random = require('random-js'); | |
// set the number of elements in the arrays | |
const elementCount = 1; // the array.find and loop joins will not complete quickly on higher numbers | |
const sampleCount = 100; | |
console.log('!!! ' + elementCount + ' elements with ' + sampleCount +' samples !!!'); | |
let r = new Random(); | |
let foo = []; | |
let bar = []; | |
let barMap = new Map(); | |
let barMapObj = {}; | |
for (let i = 0; i < elementCount; i++) { | |
let _id = r.hex(24); | |
foo[i] = { | |
_id: _id, | |
a: r.string(32), | |
b: r.integer(0, 32767), | |
c: r.bool(), | |
d: r.date(new Date(0), new Date()) | |
}; | |
bar[i] = { | |
_id: _id, | |
e: r.string(32), | |
f: r.integer(0, 32767), | |
g: r.bool(), | |
h: r.date(new Date(0), new Date()) | |
}; | |
barMap.set(_id, bar[i]); | |
barMapObj[_id] = bar[i]; | |
} | |
// first up array.find | |
var arrayFindTimer = new Measured.Timer(); | |
for (let z = 0; z < sampleCount; z++) { | |
let arrayFindSW = arrayFindTimer.start(); | |
let result = []; | |
for (let i =0; i < foo.length; i++) { | |
var item = bar.find(function (b) { return b._id === foo[i]._id; }); | |
result.push({ | |
_id: foo[i]._id, | |
a: foo[i].a, | |
b: foo[i].b, | |
c: foo[i].c, | |
d: foo[i].d, | |
e: item.e, | |
f: item.f, | |
g: item.g, | |
h: item.h | |
}); | |
} | |
arrayFindSW.end(); | |
} | |
console.log('array.find:'); | |
console.log(arrayFindTimer.toJSON()); | |
// double loop find is the next contender | |
var loopFindTimer = new Measured.Timer(); | |
for (let z = 0; z < sampleCount; z++) { | |
let loopFindSW = loopFindTimer.start(); | |
let result = []; | |
for (let i =0; i < foo.length; i++) { | |
let item = undefined; | |
for (let j =0; j < bar.length; j++) { | |
if (foo[i]._id === bar[j]._id) { | |
item = bar[j]; | |
break; | |
} | |
} | |
result.push({ | |
_id: foo[i]._id, | |
a: foo[i].a, | |
b: foo[i].b, | |
c: foo[i].c, | |
d: foo[i].d, | |
e: item.e, | |
f: item.f, | |
g: item.g, | |
h: item.h | |
}); | |
} | |
loopFindSW.end(); | |
} | |
console.log('loop:'); | |
console.log(loopFindTimer.toJSON()); | |
// merge join | |
var mergeTimer = new Measured.Timer(); | |
for (let z = 0; z < sampleCount; z++) { | |
let mergeSW = mergeTimer.start(); | |
let result = []; | |
for (let i =0; i < elementCount; i++) { | |
if (foo[i]._id === bar[i]._id) { | |
result.push({ | |
_id: foo[i]._id, | |
a: foo[i].a, | |
b: foo[i].b, | |
c: foo[i].c, | |
d: foo[i].d, | |
e: bar[i].e, | |
f: bar[i].f, | |
g: bar[i].g, | |
h: bar[i].h | |
}); | |
} else if (foo[i]._id < bar[i]._id) { | |
// outer join foo | |
result.push({ | |
_id: foo[i]._id, | |
a: foo[i].a, | |
b: foo[i].b, | |
c: foo[i].c, | |
d: foo[i].d, | |
e: undefined, | |
f: undefined, | |
g: undefined, | |
h: undefined | |
}); | |
} else { | |
// outer join foo | |
result.push({ | |
_id: bar[i]._id, | |
a: undefined, | |
b: undefined, | |
c: undefined, | |
d: undefined, | |
e: bar[i].e, | |
f: bar[i].f, | |
g: bar[i].g, | |
h: bar[i].h | |
}); | |
} | |
} | |
mergeSW.end(); | |
} | |
console.log('merge:'); | |
console.log(mergeTimer.toJSON()); | |
// next up the ES6 map object | |
var mapFindTimer = new Measured.Timer(); | |
for (let z = 0; z < sampleCount; z++) { | |
let mapFindSW = mapFindTimer.start(); | |
let result = []; | |
for (let i =0; i < foo.length; i++) { | |
var item = barMap.get(foo[i]._id); | |
result.push({ | |
_id: foo[i]._id, | |
a: foo[i].a, | |
b: foo[i].b, | |
c: foo[i].c, | |
d: foo[i].d, | |
e: item.e, | |
f: item.f, | |
g: item.g, | |
h: item.h | |
}); | |
} | |
mapFindSW.end(); | |
} | |
console.log('map:'); | |
console.log(mapFindTimer.toJSON()); | |
// finally the old school map objects turn | |
var mapObjFindTimer = new Measured.Timer(); | |
for (let z = 0; z < sampleCount; z++) { | |
let mapObjFindSW = mapObjFindTimer.start(); | |
let result = []; | |
for (let i =0; i < foo.length; i++) { | |
var item = barMapObj[foo[i]._id]; | |
result.push({ | |
_id: foo[i]._id, | |
a: foo[i].a, | |
b: foo[i].b, | |
c: foo[i].c, | |
d: foo[i].d, | |
e: item.e, | |
f: item.f, | |
g: item.g, | |
h: item.h | |
}); | |
} | |
mapObjFindSW.end(); | |
} | |
console.log('mapObj:'); | |
console.log(mapObjFindTimer.toJSON()); | |
process.exit(0); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment