Last active
January 7, 2018 04:25
-
-
Save kirilloid/14ec1da29355b6dc0523743f600747e9 to your computer and use it in GitHub Desktop.
Revisions
-
kirilloid revised this gist
Jan 7, 2018 . 2 changed files with 99 additions and 85 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1,88 +1,14 @@ function deepClone(node) { if (Array.isArray(node)) { return node.map(deepClone); } if (typeof node !== 'object' || node === null) { return node; } var copy = {}; for (var key in node) { copy[key] = deepClone(node[key]); } return copy; } 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,88 @@ // the call hirerarhcy is: suite > run > runIteration var ITERATIONS_BASE = 1e6; // reduce it for slow browsers/methods function jsonClone(x) { return JSON.parse(JSON.stringify(x)); } function message(x) { window.postMessage(x, location.origin); } function generateString () { return Math.random().toString(36).slice(2); } function runIteration(maxDepth, maxKeys, copyFn) { var totalKeys = 0; function generate(depth) { const num = depth / 2 + Math.floor(Math.random() * depth); if (num === 0 || totalKeys >= maxKeys) { totalKeys++; return generateString(); } var obj; // actually the proportion of arrays/objects almost doesn't affect executino time for most functions if (Math.random() > 0.1) { obj = {}; for (var i = 0; i < num; i++) { obj[generateString()] = generate(depth - 1); } } else { obj = []; for (var i = 0; i < num; i++) { obj.push(generate(depth - 1)); } } return obj; } var obj = generate(maxDepth); // it generates slightly more nodes, but no more than maxKeys + depth, which is negligible if (totalKeys < maxKeys) return; var start = performance.now(); copyFn(obj); return performance.now() - start; } // stats utility functions function avg(array) { return array.reduce(function(a, b) { return a + b; }, 0) / array.length; } function disp(array) { var avg2 = Math.pow(avg(array), 2); var sq2 = array.reduce(function (a, e) { return a + e * e - avg2; }, 0); return Math.sqrt(sq2) / array.length; } function run(copyFn, iterations, maxDepth, maxKeys) { var times = []; while (times.length < iterations * 1.2) { var time = runIteration(maxDepth, maxKeys, copyFn); if (time) times.push(time); } // remove top and bottom 1/12 times = times .sort(function (a, b) { return a - b; }) .slice(iterations * .1, -iterations * .1); return { avg: avg(times), // actual results seem suspiciously small, but gives some estimations anyway disp: 3 * disp(times) }; } function suite(copyFn) { [ { depth: 10, nodes: 1000 }, { depth: 10, nodes: 2000 }, { depth: 11, nodes: 3000 }, { depth: 11, nodes: 5000 }, { depth: 11, nodes: 7000 }, { depth: 12, nodes: 10000 }, { depth: 12, nodes: 14000 }, { depth: 12, nodes: 20000 }, { depth: 13, nodes: 30000 }, { depth: 13, nodes: 50000 }, { depth: 13, nodes: 70000 }, { depth: 13, nodes: 100000 } ].forEach(function (params) { var depth = params.depth; var nodes = params.nodes; var iterations = Math.max(20, Math.round(ITERATIONS_BASE / nodes / 10) * 10); console.log(nodes, run(copyFn, iterations, depth, nodes)); }); } -
kirilloid revised this gist
Jan 7, 2018 . 2 changed files with 91 additions and 62 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,24 @@ var handlers = {}; self.addEventListener('message', function (event) { if (event.origin !== location.origin) return; var key = event.data.key; var value = event.data.value; if (!handlers[key]) return; handlers[key](value); delete handlers[key]; }); var TIMEOUT_ERROR = new Error('timed out'); function cloneViaPostMessage(arg) { return new Promise(function (resolve, reject) { var randomKey = Math.random().toString(36).slice(2); handlers[randomKey] = resolve; try { self.postMessage({ key: randomKey, value: arg }, location.origin); } catch(e) { reject(e); } setTimeout(reject, 1000, TIMEOUT_ERROR); }); } 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 charactersOriginal file line number Diff line number Diff line change @@ -1,83 +1,88 @@ // the call hirerarhcy is: suite > run > runIteration var ITERATIONS_BASE = 1e6; // reduce it for slow browsers/methods function jsonClone(x) { return JSON.parse(JSON.stringify(x)); } function message(x) { window.postMessage(x, location.origin); } function generateString () { return Math.random().toString(36).slice(2); } function runIteration(maxDepth, maxKeys, copyFn) { var totalKeys = 0; function generate(depth) { const num = depth / 2 + Math.floor(Math.random() * depth); if (num === 0 || totalKeys >= maxKeys) { totalKeys++; return generateString(); } var obj; // actually the proportion of arrays/objects almost doesn't affect executino time for most functions if (Math.random() > 0.1) { obj = {}; for (var i = 0; i < num; i++) { obj[generateString()] = generate(depth - 1); } } else { obj = []; for (var i = 0; i < num; i++) { obj.push(generate(depth - 1)); } } return obj; } var obj = generate(maxDepth); // it generates slightly more nodes, but no more than maxKeys + depth, which is negligible if (totalKeys < maxKeys) return; var start = performance.now(); copyFn(obj); return performance.now() - start; } // stats utility functions function avg(array) { return array.reduce(function(a, b) { return a + b; }, 0) / array.length; } function disp(array) { var avg2 = Math.pow(avg(array), 2); var sq2 = array.reduce(function (a, e) { return a + e * e - avg2; }, 0); return Math.sqrt(sq2) / array.length; } function run(copyFn, iterations, maxDepth, maxKeys) { var times = []; while (times.length < iterations * 1.2) { var time = runIteration(maxDepth, maxKeys, copyFn); if (time) times.push(time); } // remove top and bottom 1/12 times = times .sort(function (a, b) { return a - b; }) .slice(iterations * .1, -iterations * .1); return { avg: avg(times), // actual results seem suspiciously small, but gives some estimations anyway disp: 3 * disp(times) }; } function suite(copyFn) { [ { depth: 10, nodes: 1000 }, { depth: 10, nodes: 2000 }, { depth: 11, nodes: 3000 }, { depth: 11, nodes: 5000 }, { depth: 11, nodes: 7000 }, { depth: 12, nodes: 10000 }, { depth: 12, nodes: 14000 }, { depth: 12, nodes: 20000 }, { depth: 13, nodes: 30000 }, { depth: 13, nodes: 50000 }, { depth: 13, nodes: 70000 }, { depth: 13, nodes: 100000 } ].forEach(function (params) { var depth = params.depth; var nodes = params.nodes; var iterations = Math.max(20, Math.round(ITERATIONS_BASE / nodes / 10) * 10); console.log(nodes, run(copyFn, iterations, depth, nodes)); }); } -
kirilloid created this gist
Jan 6, 2018 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,83 @@ var ITEARATIONS_BASE = 1e6; // adjust it for slow browsers // run it with testSuite(jsonClone) function jsonClone(x) { return JSON.parse(JSON.stringify(x)); } function message(x) { window.postMessage(x, location.origin); } function generateString () { return Math.random().toString(36).slice(2); } function runIteration(maxDepth, maxKeys, copyFn) { var totalKeys = 0; function generate(depth) { const num = depth / 2 + Math.floor(Math.random() * depth); if (num === 0 || totalKeys >= maxKeys) { totalKeys++; return generateString(); } var obj; if (Math.random() > 0.1) { obj = {}; for (let i = 0; i < num; i++) { obj[generateString()] = generate(depth - 1); } } else { obj = []; for (let i = 0; i < num; i++) { obj.push(generate(depth - 1)); } } return obj; } var obj = generate(maxDepth); if (totalKeys < maxKeys) return; let start = performance.now(); copyFn(obj); return performance.now() - start; } function avg(array) { return array.reduce(function(a, b) { return a + b; }, 0) / array.length; } function disp(array) { var avg2 = Math.pow(avg(array), 2); var sq2 = array.reduce(function (a, e) { return a + e * e - avg2; }, 0); return Math.sqrt(sq2) / array.length; } function run(copyFn, iterations, maxDepth, maxKeys) { var times = []; while (times.length < iterations * 1.2) { var time = runIteration(maxDepth, maxKeys, copyFn); if (time) times.push(time); } times = times .sort(function (a, b) { return a - b; }) .slice(iterations * .1, -iterations * .1); return { avg: avg(times), disp: 3 * disp(times) }; } function suite(copyFn) { [ { depth: 10, nodes: 1000 }, { depth: 10, nodes: 2000 }, { depth: 11, nodes: 3000 }, { depth: 11, nodes: 5000 }, { depth: 11, nodes: 7000 }, { depth: 12, nodes: 10000 }, { depth: 12, nodes: 14000 }, { depth: 12, nodes: 20000 }, { depth: 13, nodes: 30000 }, { depth: 13, nodes: 50000 }, { depth: 13, nodes: 70000 }, { depth: 13, nodes: 100000 } ].forEach(function (params) { var depth = params.depth; var nodes = params.nodes; var iterations = Math.max(20, Math.round(ITEARATIONS_BASE / nodes / 10) * 10); console.log(nodes, run(copyFn, iterations, depth, nodes)); }) }