0

Can someone explain to me why there is less time required when I run below code with:

for2=longTsk()  --  approx 2500ms every time

and for

for2=longTsk3() -- approx 3000ms every time

The plain for loop in both the functions requires approx 1500ms every time

function longTsk() {
  return new Promise((resolve) => {
    setImmediate(() => {
      for (let i = 0; i < 2019000000; i++) {

      }
      console.log('HOILA');
      resolve()
    });
  });
}

function longTsk3() {
  return new Promise((resolve) => {
    setImmediate(() => {
      for (let j = 0; j < 2019000000; j++) {

      }
      console.log('HOILA');
      resolve()
    });
  });
}

const date = Date.now()

async function doForAll() {

  const for1 = longTsk()
  const for2 = longTsk() //when i change this to longtsk3 exact double time is required
  await Promise.all([for1, for2])
  console.log(Date.now() - date);
}

doForAll()
console.log('sldkfgj');
console.log('lskdjglkjdfg');

The first time I ran with longTsk3 and then longTsk in this screen shot

first time i ran with longTsk3 and then longTsk in this screen shot

Why replacing the second function call with another function (longTsk3) which is similar, takes 500 ms more? This time scales may change from machine to machine, but there is significant time difference for sure in two situations when run on a same machine!

Dominik
  • 6,078
  • 8
  • 37
  • 61
  • `setImmediate` - This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future. https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate (currenlty only implemented in IE10) – Dominik Dec 28 '20 at 06:43
  • 1
    How often did you run your tests? I ran both variants several times on my machine and the the average runtimes of both variants where exactly the same. – derpirscher Dec 28 '20 at 06:51
  • Hey thanks @Dominik I didn't know that I'm actually new to nodejs but since I read somewhere "the hacky way to not block the main thread" trick so I tried that. But I don't understand why function name should make time difference in execution – nikhil valse Dec 28 '20 at 07:05
  • Thanks @derpirscher for comment, I tried it several times as I mentioned above approximate time for several iterations. I tried it with setTimeout with 0 delay also getting around the same times for executions, My machine is i5 9300h POP OS Hyperthreading ON – nikhil valse Dec 28 '20 at 07:10
  • @nikhilvalse if you're using Node then use [nextTick](https://nodejs.org/api/process.html#process_process_nexttick_callback_args) here to give the gc time to collect – Dominik Dec 28 '20 at 08:22
  • @Dominik oh I didn't get what you mean by gc time to collect is that garbage collector? I am reading the process.nextTick() you provided. – nikhil valse Dec 28 '20 at 09:02

1 Answers1

1

There is no difference in code between longTsk3 and longTsk.

The key here is that the same function is called.
and when the same function is called, the time cost is reduced.

The time spent in actual operation can be accurately measured as follows.

  1. If done separately, it takes the same amount of time.
async function doForAll() {
    const for1 = longTsk()
    const for2 = longTsk3()
    var date = Date.now()
    await Promise.all([for1])
    console.log(Date.now() - date); // 1784


    date = Date.now()
    await Promise.all([for2])
    console.log(Date.now() - date); // 1789
} 
  1. In the case of longTsk & longTsk, since it has already been executed, the cost seems to be reduced the next time it is called.
async function doForAll() {
    const for1 = longTsk()
    const for2 = longTsk()
    var date = Date.now()
    await Promise.all([for1])
    console.log(Date.now() - date); // 1789

    date = Date.now()
    await Promise.all([for2])
    console.log(Date.now() - date); // 1183
}
  1. Even when calling longTsk3 twice in a row, the exact same result as above could be obtained.
async function doForAll() {
    const for1 = longTsk3()
    const for2 = longTsk3()
    var date = Date.now()
    await Promise.all([for1])
    console.log(Date.now() - date); // 1784


    date = Date.now()
    await Promise.all([for2])
    console.log(Date.now() - date); // 1185
} 

In other words, your problem can be seen that the cost is reduced when the same function is called.

myeongkil kim
  • 2,465
  • 4
  • 16
  • 22
  • so is that the nodejs internal optimization reducing the time when only the longTsk(same function) is called twice? – nikhil valse Dec 28 '20 at 08:09
  • @nikhil valse `node.js` runs on `javascript v8 engine`. It has a `JIT (Just-In-Time) compiler`, which optimizes to `run faster` when calling the `same code`. If the same function is called twice, and the previous result `remains in memory`, it serves like cache. – myeongkil kim Dec 28 '20 at 08:54