Skip to content

Instantly share code, notes, and snippets.

@melopilosyan
Last active June 22, 2016 16:50
Show Gist options
  • Save melopilosyan/eb6b37f45ed2e71c0aa789d2a69335df to your computer and use it in GitHub Desktop.
Save melopilosyan/eb6b37f45ed2e71c0aa789d2a69335df to your computer and use it in GitHub Desktop.
String reverse functions in JavaScript with ability to compare speeds within current browser
<html>
<head>
<style>
table {
border-collapse: collapse;
}
th {
padding: 5px;
}
td {
padding: 7px;
text-align: center;
vertical-align: middle;
border: 1px solid green;
}
</style>
</head>
<body>
</body>
<script>
(function () { 'use strict';
// Change TESTS_RUN_COUNT and TEST_STRINGS_COUNT values to have more accurate test results.
var TESTS_RUN_COUNT = 100, TEST_STRINGS_COUNT = 5,
tests = [], result = [], strings = ['some text as string in JavaScript language'],
testsCount, compareBtn, i, j, c, log = console.log.bind(console),
ReverseFunctions = {
// Add here other reverse functions in this style.
reverseWithPlusEqual: function (s) {
for (var i = s.length - 1, o = ''; i >= 0; o += s.charAt(i--));
return o
},
reverseWithConcat: function (s) {
for (var i = s.length - 1, o = ''; i >= 0; o = o.concat(s.charAt(i--)));
return o
},
//// Very slow function. Don't try it
//reverseWithRegex: function(s) {
// var i, sz = s.length - 1,
// halfSz = Math.floor(sz / 2),
// replaceOne = function (s, ch, i) {
// return s.replace(new RegExp('^(.{' + i + '}).(.*)$', ''), '$1' + ch + '$2');
// };
//
// for (i = 0; i < halfSz; i++) {
// var rightIndex = sz - i, temp = s.charAt(rightIndex);
// s = replaceOne(s, s.charAt(i), rightIndex);
// s = replaceOne(s, temp, i)
// }
// return s;
//},
reverseWithArrays: function (s) {
for (var o = [], i = s.length, j = 0; i >= 0; o[j++] = s[--i]);
return o.join('')
},
reverseWithSplitJoin: function (s) {
return s.split('').reverse().join('')
},
reverseWithArrayHalf: function (s) {
s = s.split('');
var tmp, len = s.length - 1,
halfIndex = Math.floor(len / 2);
for (var i = 0; i < halfIndex; i++) {
tmp = s[len - i];
s[len - i] = s[i];
s[i] = tmp
}
return s.join('')
}
};
function display() {
var pre = document.createElement('pre');
pre.innerHTML = Array.prototype.slice.call(arguments).join('');
document.body.appendChild(pre)
}
function camelCaseToWords(s){
return s.match(/^[a-z]+|[A-Z][a-z]*/g).map(function (x) {
return x[0].toUpperCase() + x.substr(1).toLowerCase()
}).join(' ')
}
function makeTestWith(funcName, func) {
display(
'// ', camelCaseToWords(funcName), "\n",
(func + '').replace(/function\ |function/, 'function '+funcName)
);
return function (str) {
var start = 0, end = 0;
start = +new Date();
func(str);
end = +new Date();
return end - start
}
}
function initCompareButton() {
var span = document.createElement('span'),
indicator = document.createElement('div'),
button = document.createElement('button');
button.innerText = 'Compare this functions speeds';
indicator.innerHTML = 'Running test set: ';
indicator.appendChild(span);
button.onclick = function () {
button.remove();
document.body.appendChild(indicator);
runTests(constructResultTable.bind(null, this))
};
button.updateTestNumber = function (n) {
span.innerText = n
};
button.show = function () {
indicator.remove();
document.body.appendChild(button)
};
return button
}
function initStuff() {
compareBtn = initCompareButton();
// Create TEST_STRINGS_COUNT string with different length for comparing reverse functions speeds
for(i = 0; i < TEST_STRINGS_COUNT; i++) {
strings[i] || strings.push('');
for(j = 0; j < 2; j++)
strings[i] = strings[i].concat(strings[i]);
i < TEST_STRINGS_COUNT - 1 && (strings[i+1] = strings[i])
}
display('<h1>A few ways to revers strings in JavaScript</h1>');
testsCount = 0;
for (var name in ReverseFunctions) {
tests.push(makeTestWith(name, ReverseFunctions[name]));
// Create empty result array
result.push([]);
for(j = 0; j < TEST_STRINGS_COUNT; j++)
result[testsCount].push(0);
testsCount++
}
display('<h3>You can compare these functions speeds</h3>')
}
function constructResultTable() {
var tableHTML = '<table><tr> <th>String Size</th>', row = '';
for (var name in ReverseFunctions)
row += '<th>#' + name + '</th>';
tableHTML += row + '</tr>';
for(j = 0; j < TEST_STRINGS_COUNT; j++) {
row = '<tr><td>' + strings[j].length + '</td>';
for(i = 0; i < testsCount; i++) {
row += '<td>'+(result[i][j] / TESTS_RUN_COUNT).toFixed(2) + '</td>';
result[i][j] = 0;
}
tableHTML += row + '</tr>';
}
tableHTML += '</table></br></br>';
var tableEl = document.createElement('table');
tableEl.innerHTML = tableHTML;
display('Average duration in milliseconds for ' + TESTS_RUN_COUNT + ' tests per function and input string');
document.body.appendChild(tableEl);
window.scrollTo(0,document.body.scrollHeight);
return true
}
function runTests() {
var cycle = 0;
function runTestSet() {
compareBtn.updateTestNumber(++cycle);
for(i = 0; i < testsCount; i++)
for(j = 0; j < TEST_STRINGS_COUNT; j++)
result[i][j] += tests[i](strings[j]);
cycle == TESTS_RUN_COUNT ? constructResultTable() && compareBtn.show() : setTimeout(runTestSet, 1)
}
runTestSet()
}
//////////////////////////////////////////
//// MAIN :)
initStuff();
compareBtn.show();
}());
</script>
</html>
@melopilosyan
Copy link
Author

Download and open the file in your browser to see string reverse functions and compare their speeds

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