During the development or operation of an application, unforeseen issues may arise. Once your application is released to the market, the number of users is likely to increase every day, resulting in a wide range of user behaviors and collected user data. These combinations can create various error scenarios that were not caught during the previous testing processes.
One of them may be that the API response suddenly becomes slow, even with a small number of users. When checking the feature causing this issue, it seems that you have discovered or are suspecting that a certain function is taking up a significant amount of processing time. To make sure you're right, of course, you need to measure how much time that function takes to execute.
There are many ways to identify which function is slowing down your system. APM applications with good control and diagnosis capabilities can timely alert you to issues. Some APM services have real-time data collection or alerting features if they detect that a function is taking too long to execute or if the API response time is too long. However, these services are not cheap, or if they are free, they come with limitations. That's why not everyone can afford to use APM. That's when you need a "cheaper" way that is completely free and accessible to everyone.
Date.now()
, console.time()
, performance.now()
, process.hrtime()
, these are commonly used functions for measuring the time a function takes to execute. Basically, you just need to wrap the function you want to measure with these functions, and the execution time will be calculated.
The following example uses Date
to measure the execution time by subtracting the two timestamps before and after the function is called.
const start = Date.now();
await functionToBeMeasured();
const end = Date.now();
console.log(`Execution time: ${end - start} ms`);
Alternatively, you can use console.time
for a simpler approach:
console.time('executionFunctionToBeMeasured');
await functionToBeMeasured();
console.timeEnd('executionFunctionToBeMeasured');
console.time
does not provide high accuracy. If you want sub-millisecond accuracy, you can use more powerful functions like performance.now()
or process.hrtime()
if you are using Node.js.
const start = performance.now();
await functionToBeMeasured();
const end = performance.now();
console.log(`Execution time: ${end - start} ms`);
After knowing how to measure the execution time, another issue arises: we need to wrap the function to be measured between the two time measurement functions. This causes code disruption in your project, requiring more modifications, making the code more cumbersome and difficult to control.
The idea here is to write a function to encapsulate the time measurement feature. The input is the function to be measured, and the output is the result of that function along with the execution time. Something like this:
calcExecuteTime(functionToBeMeasured);
Sometimes, functionToBeMeasured
takes arguments, so let's make a slight modification:
calcExecuteTime(() => functionToBeMeasured(arg1, arg2...));
If functionToBeMeasured
uses this
, add a context
parameter to receive this
from the caller:
calcExecuteTime(context, () => functionToBeMeasured(arg1, arg2...));
Lastly, it is a good idea to add a name
parameter to identify where the function is called from:
calcExecuteTime(name, context, () => functionToBeMeasured(arg1, arg2...));
The calcExecuteTime
function can look like this:
const calcExecuteTime = async (name, context, fn) => {
const start = process.hrtime();
const result = await fn.call(context);
const stop = process.hrtime(start);
const executionTime = (stop[0] * 1e9 + stop[1]) / 1e9;
console.log(`${name} execution time: ${executionTime}s`);
return result;
};
Now let's try calling the function:
calcExecuteTime("Execute ToBeMeasured", this, () => functionToBeMeasured(arg1, arg2...));
// Execute ToBeMeasured execution time: 0.000178s
You can also modify the function according to your needs, for example, instead of logging the execution time using console.log
, you can log it to somewhere else. Or enhance the function by adding a toggle flag to enable/disable the measuring feature.
References:
5 profound lessons
Every product comes with stories. The success of others is an inspiration for many to follow. 5 lessons learned have changed me forever. How about you? Click now!
Subscribe to receive new article notifications
Hello, my name is Hoai - a developer who tells stories through writing ✍️ and creating products 🚀. With many years of programming experience, I have contributed to various products that bring value to users at my workplace as well as to myself. My hobbies include reading, writing, and researching... I created this blog with the mission of delivering quality articles to the readers of 2coffee.dev.Follow me through these channels LinkedIn, Facebook, Instagram, Telegram.
Comments (1)