Skip to content
Advertisement

Why is the split() method approx. 2x slower when the result is pushed to an array?

Consider the following code snippet:

function split() {
  let time = 0;
  let result = [];
  for (let i = 0; i < 10 * 1000 * 1000; i++) {
    let start = performance.now();
    let words = "foo bar baz".split(" ");
    let end = performance.now();
    time += (end - start);
    // result.push(words);
  }
  console.log(`Time needed: ${time}ms`);
}

The output of this code is something like:

Time needed: 2664ms.

However, with the line // result.push(words); uncommented, the output is something like:

Time needed: 4991ms.

That’s approx. 2x slower (note that I’m measuring only the time needed by split(), but not push()). Can someone explain me why?

Advertisement

Answer

performance.now() does not have the necessary accuracy to measure what you’re trying to measure. The browser deliberately returns an inaccurate number from performance.now() in order to combat exploits like spectre. So in both cases, the numbers you are seeing are not going to be accurate.

As for why you’re getting different inaccurate numbers, here’s my speculation. I’m guessing that most of the time, end - start is 0, because both timestamps are rounded to the same thing. So what you’re really counting is the number of times where the rounding of the timestamp flips from one number to the next. Your first code might run through the loop 10 times, with 9 of them reporting 0ms, and 1 of them reporting 1ms. But then when you make the whole thing take longer, now it only takes 5 times through the loop for enough time to elapse that the rounding goes the other way. And so out of 10 times through the loop, 8 report 0ms and 2 report 1ms.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement