Skip to content

Instantly share code, notes, and snippets.

@JobLeonard
Last active March 27, 2017 19:03
Show Gist options
  • Save JobLeonard/8189f091cefafb2999c9779ecac45da4 to your computer and use it in GitHub Desktop.
Save JobLeonard/8189f091cefafb2999c9779ecac45da4 to your computer and use it in GitHub Desktop.
look-up table vs Function-switch object (http://jsbench.github.io/#8189f091cefafb2999c9779ecac45da4) #jsbench #jsperf
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>look-up table vs Function-switch object</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/1.0.0/benchmark.min.js"></script>
<script src="./suite.js"></script>
</head>
<body>
<h1>Open the console to view the results</h1>
<h2><code>cmd + alt + j</code> or <code>ctrl + alt + j</code></h2>
</body>
</html>
"use strict";
(function (factory) {
if (typeof Benchmark !== "undefined") {
factory(Benchmark);
} else {
factory(require("benchmark"));
}
})(function (Benchmark) {
var suite = new Benchmark.Suite;
Benchmark.prototype.setup = function () {
// pseudo-normal distribution around zero, in the range [-50,50)
var randomData = new Array(50000);
for (let i = 0; i < randomData.length; i++) {
randomData[i] = (Math.random(100) + Math.random(100) + Math.random(100) - Math.random(100) - Math.random(100) - Math.random(100)) / 6
}
var min = -50;
var max = 50;
// 257 element palette
var solar256 = [
'#ffffff',
'#ffffcc', '#fffeca', '#fffdc8', '#fffcc6', '#fffcc4', '#fffac1', '#fffabf', '#fff8bc', '#fff7ba', '#fff7b7', '#fff5b5', '#fff4b2', '#fff4b0', '#fff2ae', '#fff1ab', '#fff1a9', '#fff0a6', '#ffefa4', '#ffeda1', '#ffec9f', '#ffeb9d', '#ffea9b', '#ffea99', '#ffe897', '#ffe895', '#ffe793', '#ffe590', '#ffe48e', '#ffe48c', '#ffe28a', '#ffe188', '#ffe085', '#ffdf82', '#fede80', '#fede80', '#fedd7e', '#fedc7b', '#feda79', '#fed976', '#fed774', '#fed673', '#fed572', '#fed571', '#fed370', '#fed36f', '#fed26e', '#fed06d', '#ffcf6b', '#ffce6a', '#ffcd69', '#ffcc67', '#ffca66', '#ffc965', '#ffc763', '#ffc762', '#ffc561', '#ffc460', '#ffc35f', '#ffc25e', '#ffc15c', '#ffc05b', '#ffbf5a', '#ffbd58', '#febd57', '#febc56', '#febb55', '#feba54', '#feb953', '#feb751', '#feb550', '#feb54f', '#feb34e', '#feb34d', '#feb14c', '#feb04b', '#feae4a', '#feae4a', '#feac49', '#feab49', '#fea948', '#fea848', '#fea747', '#fea747', '#fea446', '#fea445', '#fea345', '#fea145', '#fe9f44', '#fe9e43', '#fe9e43', '#fe9b42', '#fe9b42', '#fe9941', '#fe9841', '#fe9740', '#fd9640', '#fd953f', '#fd943f', '#fd923e', '#fd913d', '#fd8f3d', '#fd8e3d', '#fd8c3c', '#fd8b3b', '#fd8a3b', '#fd883a', '#fd883a', '#fd8539', '#fd8439', '#fd8339', '#fd8138', '#fd8138', '#fd7e37', '#fd7e37', '#fd7b36', '#fd7a36', '#fd7935', '#fd7835', '#fd7534', '#fd7434', '#fd7233', '#fd7133', '#fd6f32', '#fd6e32', '#fd6d32', '#fd6a31', '#fd6931', '#fd6730', '#fd6530', '#fd652f', '#fd632f', '#fd602e', '#fd5e2e', '#fd5d2d', '#fd5b2d', '#fd5a2d', '#fc582c', '#fc572c', '#fc542b', '#fc522b', '#fc512b', '#fc4e2a', '#fc4d2a', '#fa4c29', '#fa4b29', '#f94928', '#f94828', '#f84727', '#f74627', '#f64527', '#f54326', '#f54226', '#f44126', '#f33f25', '#f23e25', '#f23c24', '#f13c24', '#f03a23', '#f03823', '#ef3723', '#ef3622', '#ee3422', '#ed3321', '#ec3121', '#eb3021', '#ea2e20', '#ea2c20', '#e92b1f', '#e8291f', '#e8281f', '#e7261e', '#e7241e', '#e6221d', '#e51f1d', '#e41f1d', '#e31c1c', '#e21a1c', '#e1191d', '#e0191d', '#df171d', '#de171e', '#dc161e', '#db161f', '#da151f', '#d9141f', '#d81320', '#d61320', '#d51120', '#d41121', '#d31021', '#d20f21', '#d00f22', '#cf0d22', '#ce0d22', '#cd0c23', '#cb0b23', '#ca0a23', '#c90923', '#c80824', '#c60724', '#c60624', '#c40525', '#c30425', '#c20325', '#c10225', '#bf0226', '#be0026', '#bc0026', '#bb0026', '#ba0026', '#b90026', '#b80026', '#b60026', '#b50026', '#b40026', '#b20026', '#b10026', '#b00026', '#ae0026', '#ac0026', '#ab0026', '#ab0026', '#a80026', '#a70026', '#a60026', '#a50026', '#a40026', '#a20026', '#a20026', '#a00026', '#9e0026', '#9d0026', '#9c0026', '#9a0026', '#990026', '#980026', '#970026', '#960026', '#940026', '#930026', '#920026', '#910026', '#900026', '#8d0026', '#8d0026', '#8c0026', '#8a0026', '#880026', '#870026', '#870026', '#850026', '#830026', '#820026', '#820026', '#800026'
];
// 20 element palette
var category20 = [
'#ffffff', // White for zeros
'#1f77b4',
'#ff7f0e',
'#2ca02c',
'#d62728',
'#9467bd',
'#8c564b',
'#e377c2',
'#7f7f7f',
'#bcbd22',
'#17becf',
'#9edae5',
'#aec7e8',
'#ffbb78',
'#98df8a',
'#ff9896',
'#c5b0d5',
'#c49c94',
'#f7b6d2',
'#c7c7c7',
'#dbdb8d',
];
function createLookUpFunction(_palette, min, max) {
const idxScale = ((_palette.length - 1) / (max - min) || 1);
let stringBuild = [];
stringBuild.push('var i = ((cIdx - ' + min + ')*' + idxScale + ')|0;\n');
stringBuild.push('if ( i == 0 ) return "' + _palette[0] + '";\n');
for (let i = 1; i < _palette.length; i++) {
stringBuild.push('else if ( i == ' + i + ' ) return "' + _palette[i] + '";\n');
}
console.log(stringBuild.join(''));
return new Function('cIdx', stringBuild.join(''));
}
function createArrayLookUpFunction(_palette, min, max) {
const idxScale = ((_palette.length - 1) / (max - min) || 1);
let stringBuild = [];
stringBuild.push('var output = new Array(cIdx.length);\n')
stringBuild.push('var i = cIdx.length; while(i--){\n');
stringBuild.push('\tvar idx = ((cIdx[i] - ' + min + ')*' + idxScale + ')|0, out = "";\n');
stringBuild.push('\tif ( idx == 0 ) out = "' + _palette[0] + '";\n');
for (let i = 1; i < _palette.length; i++) {
stringBuild.push('\telse if ( idx == ' + i + ' ) out = "' + _palette[i] + '";\n');
}
stringBuild.push('\toutput[i] = out;\n}\n')
stringBuild.push('return output;\n');
console.log(stringBuild.join(''));
return new Function('cIdx', stringBuild.join(''));
}
function createArrayLookUpFunction2(_palette, min, max) {
const idxScale = ((_palette.length - 1) / (max - min) || 1);
let stringBuild = [];
stringBuild.push('var output = new Array(cIdx.length);\n')
stringBuild.push('var i = cIdx.length; while(i--){\n');
stringBuild.push('\tvar idx = ((cIdx[i] - ' + min + ')*' + idxScale + ')|0, out = ""')
for(let i = 0; i < _palette.length; i++) {
stringBuild.push(', p' + i + ' = "' + _palette[i] + '"');
}
stringBuild.push(';\n\tif ( idx == 0 ) out = "' + _palette[0] + '";\n');
for (let i = 1; i < _palette.length; i++) {
stringBuild.push('\telse if ( idx == ' + i + ' ) out = p' + i + ';\n');
}
stringBuild.push('\toutput[i] = out;\n}\n')
stringBuild.push('return output;\n');
console.log(stringBuild.join(''));
return new Function('cIdx', stringBuild.join(''));
}
var LUF = createLookUpFunction(category20, min, max);
var ALUF = createArrayLookUpFunction(category20, min, max);
var ALUF2 = createArrayLookUpFunction2(category20, min, max);
};
suite.add("palette lookup", function () {
// palette lookup
let i = randomData.length;
let output = new Array(i);
const idxScale = ((palette.length - 1) / (max - min) || 1);
while (i--){
output[i] = ((randomData[i]-min)*idxScale)|0;
}
});
suite.add("function lookup", function () {
// function lookup
let i = randomData.length;
let output = new Array(i);
while (i--){
output[i] = LUF(randomData[i]);
}
});
suite.add("function lookup vectorised", function () {
// function lookup vectorised
var output = ALUF(randomData);
});
suite.add("function lookup vectorised, reuse strings", function () {
// function lookup vectorised, reuse strings
var output = ALUF2(randomData);
});
suite.on("cycle", function (evt) {
console.log(" - " + evt.target);
});
suite.on("complete", function (evt) {
console.log(new Array(30).join("-"));
var results = evt.currentTarget.sort(function (a, b) {
return b.hz - a.hz;
});
results.forEach(function (item) {
console.log((idx + 1) + ". " + item);
});
});
console.log("look-up table vs Function-switch object");
console.log(new Array(30).join("-"));
suite.run();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment