Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save johnspackman/0c7056c6de55d1a1e010e79cd8db4ec6 to your computer and use it in GitHub Desktop.
Save johnspackman/0c7056c6de55d1a1e010e79cd8db4ec6 to your computer and use it in GitHub Desktop.
var t = this;
var FUNCTION_TESTS = [
{
title: "qx.Bootstrap.isFunction",
fn: function() {
return qx.Bootstrap.isFunction(qx.Bootstrap.isFunction);
}
},
{
title: "typeof function",
fn: function() {
return typeof qx.Bootstrap.isFunction === "function";
}
}
];
var INDEXOF_TESTS = (function() {
var DUMMY_ARRAY = [];
for (var i = 0; i < 10000; i++)
DUMMY_ARRAY.push(i);
function indexOf(value) {
for (var i = 0; i < this.length; i++)
if (this[i] === value)
return i;
return -1;
}
/*
* Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
* with a few minor tweaks for performance (otherwise it is much slower than Array.indexOf). See
* comments marked "JS Note" for changes.
*/
function mozIndexOf(searchElement, fromIndex) {
// 1. Let o be the result of calling ToObject passing
// the this value as the argument.
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let lenValue be the result of calling the Get
// internal method of o with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = o.length >>> 0;
// 4. If len is 0, return -1.
if (len === 0) {
return -1;
}
// 5. If argument fromIndex was passed let n be
// ToInteger(fromIndex); else let n be 0.
var n = 0;
// JS Note: Explicit test for fromIndex!==undefined because coercion is very expensive
if (fromIndex !== undefined)
n = +fromIndex||0;
if (Math.abs(n) === Infinity) {
n = 0;
}
// 6. If n >= len, return -1.
if (n >= len) {
return -1;
}
// 7. If n >= 0, then Let k be n.
// 8. Else, n<0, Let k be len - abs(n).
// If k is less than 0, then let k be 0.
// 9. Repeat, while k < len
// JS Note: switch to for loop, with index var (k) in the declaration
for (var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); k < len; k++) {
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the
// HasProperty internal method of o with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
// i. Let elementK be the result of calling the Get
// internal method of o with the argument ToString(k).
// ii. Let same be the result of applying the
// Strict Equality Comparison Algorithm to
// searchElement and elementK.
// iii. If same is true, return k.
// JS Note: Swapped these two round because "in" has quite a performance hit
if (o[k] === searchElement && k in o) {
return k;
}
}
return -1;
}
return [
{
title: "Array.indexOf",
fn: function() {
DUMMY_ARRAY.indexOf("blah");
}
},
{
title: "DIY indexOf",
fn: function() {
indexOf.call(DUMMY_ARRAY, "blah")
}
},
{
title: "Mozilla Polyfill indexOf",
fn: function() {
mozIndexOf.call(DUMMY_ARRAY, "blah")
}
}
];
})();
function runPerfTest(config, count) {
var start = window.performance.now();
for (var i = 0; i < count; i++)
config.fn();
var end = window.performance.now();
var diff = end-start;
return diff;
}
function runPerfTests(configs, count) {
configs.forEach(function(config) {
config.times = [];
delete config.data;
for (var i = 0; i < 20; i++) {
var diff = runPerfTest(config, count);
config.times.push(diff);
}
});
}
function analyse(configs) {
configs.forEach(function(config) {
var data = config.data = {
min: null,
max: null,
total: 0
};
config.times.forEach(function(val) {
data.min = data.min === null ? val : Math.min(val);
data.max = data.max === null ? val : Math.max(val);
data.total += val;
});
data.avg = data.total / config.times.length;
t.debug(config.title + " " + JSON.stringify(data));
});
}
runPerfTests(INDEXOF_TESTS, 1000);
analyse(INDEXOF_TESTS);
@johnspackman
Copy link
Author

Here’s an interesting performance test with arrays - apparently it’s quite well known that Array.indexOf is slower than just a for loop, but it is possible to use the Mozilla MDN polyfill for Array.indexOf to get similar peformance to a for loop.

In Chrome 52 beta the figures are quite similar but Firefox shows a 3x boost and Safari 5x.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment