0

I'm trying to compare the difference in terms of execution time in JS between running some expressions sequentially versus running the same expressions within a function call.

Given the following code:

const t1 = Date.now();

console.log(Array.from(Array(500)).map((i, idx) => idx));

const t2 = Date.now();

console.log('t=', t2 - t1, 'ms', t2, t1);


function traverseArrAndPrint() {
    console.log(Array.from(Array(500)).map((i, idx) => idx));
}


const t3 = Date.now();

traverseArrAndPrint();

const t4 = Date.now();

console.log('t=', t4 - t3, 'ms', t4, t3);

Now look at the output:

node a.js
[
   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,
  12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
  24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
  36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
  72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
  84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  96, 97, 98, 99,
  ... 400 more items
]
t= 8 ms 1620926365937 1620926365929
[
   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,
  12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
  24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
  36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
  72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
  84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  96, 97, 98, 99,
  ... 400 more items
]
t= 1 ms 1620926365938 1620926365937

Why would a function call take less time to execute than the sequential expressions before it?

Fernando Gabrieli
  • 980
  • 3
  • 15
  • 31
  • 2
    *"...between running some expressions sequentially versus running the same expressions within a function call..."* They're still sequential whether they're in a function call or not. But fundamentally this is what we call a "naive micro-benchmark" and they're not useful with JavaScript engines. – T.J. Crowder May 13 '21 at 17:31
  • 1
    Side note: Prefer `Array.from({length:500})` to `Array.from(Array(500))`. On some JavaScript engines (including V8, which is used in the Chromium-based browsers) that `Array(500)` will actually allocate memory for 500 elements as an optimization, but you're going to throw that array away... – T.J. Crowder May 13 '21 at 17:34
  • 1
    Did you try to reverse the execution order (having the function run first) ? hint: this is not how benchmarking is done :) – Nir Alfasi May 13 '21 at 17:34
  • 1
    Side note 2: `Array.from` has mapping built in, so you can use `Array.from({length:500}, (i, idx) => idx)` if you like. – T.J. Crowder May 13 '21 at 17:34
  • 3
    what you're testing here it the performance of `console.log`, not of your expressions. – georg May 13 '21 at 17:35
  • 1
    @georg - Well, the combination of the two, but it's a very good point to raise as `console.log` is going to be fairly heavy. – T.J. Crowder May 13 '21 at 17:36
  • 1
    You might look at benchmarking tools like `benchmark.js` (which is used by https://esbench.com/ and others). – T.J. Crowder May 13 '21 at 17:37
  • @T.J.Crowder yes, i'm sorry i used the word 'sequentially' i just wanted to note what i was referring to but you are right about this, all of them are sequentially executed. Copy that about Array.from{length} i didn't know, thank you. – Fernando Gabrieli May 13 '21 at 17:38
  • 1
    @FernandoGabrieli - I didn't realize they did that until recently either. :-) – T.J. Crowder May 13 '21 at 17:39
  • @georg i just wanted to figure out the difference between executing these expressions within a function call and outside of it – Fernando Gabrieli May 13 '21 at 17:40
  • all of this came from in the first place (i just want to tell all of you besides thanking you for the quick answers) because i'm trying to compare the performance within an angular template between executing method calls and plain expressions; but now i was just surprised by the result within this node script – Fernando Gabrieli May 13 '21 at 17:41
  • 2
    @FernandoGabrieli In general, a function will be compiled and optimised separately, and likely different. Whether that's a benefit for performance or not differs from case to case. If you wonder about an Angular template, **you must benchmark** that **specific** Angular template. – Bergi May 13 '21 at 17:42
  • @NirAlfasi when reverting the order, calling the function first and then the code outside a function call, result is the same, amazing, 9ms vs 1ms i think im missing knowledge on the internals of how this code is handled, what should i read? – Fernando Gabrieli May 13 '21 at 17:44
  • thank you @Bergi i will look into that, could you recommend a good read on how this is handled internally? – Fernando Gabrieli May 13 '21 at 17:47
  • 1
    @FernandoGabrieli https://mrale.ph/blog/2012/12/15/microbenchmarks-fairy-tale.html https://stackoverflow.com/a/60635905/1048572 (not because they describe how the internals work, but because they make good arguments that you should not care) – Bergi May 13 '21 at 17:55

0 Answers0