Skip to content

Instantly share code, notes, and snippets.

@JobLeonard
Last active March 24, 2017 14:04
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 JobLeonard/cbfad9d07c549532aceb79f8b051553e to your computer and use it in GitHub Desktop.
Save JobLeonard/cbfad9d07c549532aceb79f8b051553e to your computer and use it in GitHub Desktop.
charAt vs array lookup + string vs array indexOf comparison (http://jsbench.github.io/#cbfad9d07c549532aceb79f8b051553e) #jsbench #jsperf
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>charAt vs array lookup + string vs array indexOf comparison</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 () {
"use strict";
/**
* @param {[]} array - sorted array
* @param {*} element - element in array
*/
function binaryIndexOf(array, element) {
let minIdx = 0, maxIdx = array.length - 1, idx, cElement;
while (minIdx <= maxIdx) {
idx = ((minIdx + maxIdx) * 0.5) | 0;
cElement = array[idx];
if (cElement < element) {
minIdx = idx + 1;
} else if (cElement > element) {
maxIdx = idx - 1;
} else {
return idx;
}
}
return -1;
}
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var keyArray = keyStr.split('');
var sortedArray = keyStr.split('').sort();
var sortedStr = sortedArray.join('');
var sortedMiddle = sortedArray[(sortedArray.length/2) | 0];
var randomIndices = [];
for (var i = 0; i < 10000; i++){
randomIndices.push((keyArray.length * Math.random())|0);
}
var randomInput = [], sortedInput = [];
for (var i = 0; i < randomIndices.length; i++){
randomInput.push(keyArray[randomIndices[i]]);
sortedInput.push(sortedArray[randomIndices[i]]);
}
var keyDict = {};
for (let i = 0; i < keyStr.length; i++){
keyDict[keyStr.charAt(i)] = i;
}
};
suite.add("encode string charAt()", function () {
// encode string charAt()
var output = []
for (var i = 0; i < randomIndices.length; i++){
output.push(keyStr.charAt(randomIndices[i]));
}
});
suite.add("encode array indexing", function () {
// encode array indexing
var output = []
for (var i = 0; i < randomIndices.length; i++){
output.push(keyArray[randomIndices[i]]);
}
});
suite.add("decode string indexOf (linear search)", function () {
// decode string indexOf (linear search)
var output = [];
for (var i = 0; i < randomInput.length; i++){
output.push(keyStr.indexOf(randomInput[i]));
}
});
suite.add("decode array indexOf (linear search)", function () {
// decode array indexOf (linear search)
var output = [];
for (var i = 0; i < randomInput.length; i++){
output.push(keyArray.indexOf(randomInput[i]));
}
});
suite.add("decode sorted array indexOf (linear search)", function () {
// decode sorted array indexOf (linear search)
var output = [];
for (var i = 0; i < sortedInput.length; i++){
output.push(sortedArray.indexOf(sortedInput[i]));
}
});
suite.add("decode string inline binary search", function () {
// decode string inline binary search
var output = [];
for (var i = 0; i < sortedInput.length; i++){
var out = -1, minIdx = 0, maxIdx = sortedArray.length - 1, idx, cElement, element = sortedInput[i];
while (minIdx <= maxIdx) {
idx = ((minIdx + maxIdx) * 0.5) | 0;
cElement = sortedStr.charAt(idx);
if (cElement < element) {
minIdx = idx + 1;
} else if (cElement > element) {
maxIdx = idx - 1;
} else {
out = idx;
break;
}
}
output.push(out);
}
});
suite.add("decode sorted array binaryIndexOf (binary search)", function () {
// decode sorted array binaryIndexOf (binary search)
var output = [];
for (var i = 0; i < sortedInput.length; i++){
output.push(binaryIndexOf(sortedArray, sortedInput[i]));
}
});
suite.add("decode array inline binary search", function () {
// decode array inline binary search
var output = [];
for (var i = 0; i < sortedInput.length; i++){
var out = -1, minIdx = 0, maxIdx = sortedArray.length - 1, idx, cElement, element = sortedInput[i];
while (minIdx <= maxIdx) {
idx = ((minIdx + maxIdx) * 0.5) | 0;
cElement = sortedArray[idx];
if (cElement < element) {
minIdx = idx + 1;
} else if (cElement > element) {
maxIdx = idx - 1;
} else {
out = idx;
break;
}
}
output.push(out);
}
});
suite.add("decode sorted array single-pass binary search/linear search hybrid", function () {
// decode sorted array single-pass binary search/linear search hybrid
var output = [], middle = (sortedArray.length/2)|0;
for (var i = 0; i < sortedInput.length; i++){
var val = sortedInput[i];
output.push(val < sortedMiddle ? sortedArray.indexOf(val, 0) : sortedArray.indexOf(val, middle));
}
});
suite.add("decode sorted string single-pass binary search/linear search hybrid", function () {
// decode sorted string single-pass binary search/linear search hybrid
var output = [], middle = (sortedStr.length/2)|0;
for (var i = 0; i < sortedInput.length; i++){
var val = sortedInput[i];
output.push(val < sortedMiddle ? sortedStr.indexOf(val, 0) : sortedStr.indexOf(val, middle));
}
});
suite.add("decode dict", function () {
// decode dict
var output = [];
for (var i = 0; i < randomInput.length; i++){
output.push(keyDict[randomInput[i]]);
}
});
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("charAt vs array lookup + string vs array indexOf comparison");
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