Performance in "Reverse a string" writing readable (human friendly) code

Tell us what’s happening:
Describe your issue in detail here.

I’m playing with this challenge. This sol. is probably not very performant. I thought using Array.split, reverse & join, but I guess this would be slower because more variables are defined, and I didn’t really want to use Array.reverse().

Using

const i =Date.now();
reverseString("hello");
const f = Date.now();
console.log(f-i);

does log 0, How to measure performance here?

Any suggestion on more performant but easy-to-read solutions are welcome.

  **Code so far**
function reverseString(str) {
  const length = str.length;
  let reversed = "", i=0;
  while(i<length){
  reversed=str[i]+reversed;
  i++;
}
  str=reversed;
  return str;
}

console.log(reverseString("hello"));

**Challenge:**  Reverse a String

**Link to the challenge:**
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/reverse-a-string
const start = performance.now();
for (let i = 0; i < 1e4; i++) {
  reverseString("test");
}
const end = performance.now();
console.log(end - start);

That’ll run it 10000 times and log the time. Difference is likely to be trivial.

EDIT:

So running the following in the browser console, I have to whack it up to a million runs of each function to even get a noticeable difference:

const RUNS = 1e6

function revString1 (str) {
  return str.split("").reverse().join("");
}

function revString2 (str) {
  let reversedStr = "";
  for (let i = 0; i < str.length; i++) {
    reversedStr = str[i] + reversedStr;
  }
  return reversedStr;
}

const start1 = performance.now();
for (let i = 0; i < RUNS; i++) {
  revString1("test test test");
}
const end1 = performance.now();

const start2 = performance.now();
for (let i = 0; i < RUNS; i++) {
  revString2("test test test");
}
const end2 = performance.now();


console.log(`Total execution time for ${RUNS.toString()} runs of revString1 is ${end1 - start1} milliseconds`);
console.log(`Average execution time for revString1 is ${(end1 - start1) / RUNS} milliseconds`);

console.log(`Total execution time for ${RUNS.toString()} runs of revString2 is ${end2 - start2} milliseconds`);
console.log(`Average execution time for revString2 is ${(end2 - start2) / RUNS} milliseconds`);

So a million runs gives me this:

  • Total execution time for 1000000 runs of revString1 is 460 milliseconds
  • Average execution time for revString1 is 0.00046 milliseconds
  • Total execution time for 1000000 runs of revString2 is 376 milliseconds
  • Average execution time for revString2 is 0.000376 milliseconds

Notice that the average difference in execution time is a few microseconds.

This is extremely naïve, and based on the same string being used over and over, so randomising the input in terms of length and giving the same random set of a million different strings to each function may show some more apparent differences. It’s also based on one single JS engine in one browser, Chrome may show completely different results, for example.

1 Like

Just as an addendum: here’s a good talk – the examples are in lower-level code than JS (he’s talking about C/C++). The first ten minutes are all you really need to watch (he then goes into statistical measurement). Despite your example being JS, what he talks about there is a good illustration of why what you think you’re trying to do here is quite probably not what you are actually doing. JS engines do a lot of stuff to optimise, so there’s that, which feeds into the extremely naïve test I showed being basically meaningless. You’re trying to make micro-optimisations when you have no idea whether you’re actually optimising anything. The minuscule difference in performance here is almost indistinguishable from random noise.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.