A Duv
A Duv

Reputation: 403

JS performance.now() and console.time() inaccurate in Nodejs?

I'm relatively new to JS, and was trying to benchmark some code (to study performance of various algorithms) so I could just see how long things took when running on my terminal. I originally had:

function benchmark(callback, name = `${callback+""}`) { // Convert callback to literal string if no name provided
  console.log(`${name}`);
  console.time("time");
  console.log(`\t${callback}`);
  console.timeEnd("time");
  console.log('\n');
}

However, I am not receiving the time it takes to run the function. For example, my output states it takes longer to find the 6th fibonacci number than the 50th.

Example 1:

function fib(n) {
  if (n === 1 || n === 2) return 1;
  return fib(n - 1) + fib(n - 2);
}

When I run:

benchmark(fib(6), "fib(6) Rep 1");    // 0.5449770092964172ms
benchmark(fib(50), "fib(50) Rep 1"); //  0.004218995571136475ms

It takes longer for fib(50) to finish, but the measured time is shorter!

Modified benchmark via performance.now() also doesn't work

I run into the same issue above if I use performance.now().

const {performance} = require('perf_hooks');
function benchmark(callback, name = `${callback+""}`) {
  let t0 = performance.now();
  let result = callback;
  let t1 = performance.now();
  console.log(`\t${result}`);
  console.log(`time: ${t1 - t0}ms`);
  console.log('\n');
};

I suspect the timers are stopping randomly or before the call is over. Should I convert the callback to a promise, and use either .then or await? Or am I missing something more fundamental about JS (like the event loop or call stack)?

I've gone through:

Upvotes: 1

Views: 2068

Answers (1)

A Duv
A Duv

Reputation: 403

Klaycon solved this for me in the comment above but can't post an answer for some reason. I was passing in a number (and not a callback); I was evaluating the callback BEFORE the timers.

To resolve my issue, I first need to pass an actual callback into my benchmark() function:

  benchmark( () => fib(6), "fib(6) Rep 1");

and then I need to invoke my callback in my benchmark function itself:

function benchmark(callback, name = `${callback + ""}`) {
  console.log(`${name}`);
  console.time("time");
  console.log(`\t${callback()}`);          // ##### CHANGE HERE ######
  console.timeEnd("time");
  console.log('\n');
}

Upvotes: 4

Related Questions