- Javascript время выполнения скрипта
- 2. Console time
- 3. Performance timers
- Measuring JavaScript execution time in Unit tests
- Как измерить время выполнения скрипта
- Measure execution times in browsers & Node.js
- Business Logic
- Console Timers ( console.time )
- High Resolution Timers ( performance.now )
- Time tracking util
- Performance Hooks ( perf_hooks )
- TypeScript Typings
- Performance Observer
- Performance Marks ( performance.mark )
- Performance Instrumentation ( performance.timerify )
- Completion of measurement
- Inclusion in Unit Tests
- Get connected 🔗
Javascript время выполнения скрипта
The easiest way to track execution time is to use a date object. Using Date.now() that returns the total number of milliseconds elapsed since the Unix epoch, we can store the value before and after the execution of the function to be measured and then get the difference of the two.
const start = Date.now(); await functionToBeMeasured(); const end = Date.now(); console.log(`Execution time: $ ms`);
2. Console time
Another easy solution is to use a console timer. The console.time() method starts a timer with a label. And a subsequent call to the console.timeEnd() method with the same label will output the time elapsed since the method was started.
console.time('Execution Time'); await functionToBeMeasured(); console.timeEnd('Execution Time');
3. Performance timers
Console timers do not provide high accuracy. If we want accuracy in 1-millisecond increments, we can use high-resolution timers like performance.now() . It also avoids some synchronization issues with the system clock.
const start = performance.now(); await functionToBeMeasured(); const end = performance.now(); console.log(`Execution time: $ ms`);
Note: If measuring in Node, process.hrtime.bigint() returns accuracy in nanoseconds. This covers the ways of measuring JavaScript execution time. If we run into a scenario wherein we want to start measuring JavaScript execution time for multiple functions, we can make use of the Performance API and Performance Observer. They provide markers to track multiple entries and measure them independently.
Measuring JavaScript execution time in Unit tests
For ensuring execution of functions is fast enough, it can be made a part of our unit tests. Many frameworks (Jest, Jasmine, etc.) allow setting of a timeout for the execution of a test. The timeout feature can then be used to fail a test if the method takes longer to execute. With Jasmine:
describe('testing time duration', () => < it('does not take longer than 5 seconds', async () =>< await functionToBeMeasured(); >, 5000); >);
Как измерить время выполнения скрипта
Сегодня мы рассмотрим, сколько именно времени уходит у блока кода, чтоб выполнить свою работу?
В этом уроке вы узнаете два наиболее классических способа по измерению времени работы вашего скрипта. Данные подходы помогут вам ускорить работу вашего приложения и найти те участки кода, которые работают медленнее, чтоб оптимизировать их.
Итак, первый способ, это использование специального метода в объекте console. Все знакомы с методом console.log(), с помощью которого можно выводить сообщения и смотреть отладочную информацию и ошибки. Кроме console.log() у объекта console существует метод time со специальным синтаксисом, который позволяет буквально в две строки замерять время выполнения блока вашего кода.
Для того, чтоб этот метод заработал, требуется в начале блока, который вы хотите непосредственно замерять, указать console.time() с ключом, как уникальным идентификатором, в нашем случае это будет FirstWay.
Далее идёт ваш блок кода, в нашем случае, это небольшая функция someFunction(). Когда ваш код уже выполнен и необходимо посмотреть на результат, сколько времени заняло его выполнение, вызывается специальный метод console.timeEnd() с тем же самым ключом, который вы задавали ранее.
function someFunction() < //Ждём несколько секунд alert("Waiting. ") >console.time('FirstWay'); someFunction(); console.timeEnd('FirstWay');
Таким образом, мы устанавливаем начало и конец замера времени выполнения работы кода. Результат такого замера мы сможем увидеть в консоли. Данные выводятся в миллисекундах.
Второй вариант считается более классическим подходом. В этом варианте больше строчек кода, но потребность в консоли отпадает. В этом методе требуется создать константу start. В ней мы объявляем объект new Date() с методом getTime() для установления начала отсчёта замера.
const start = new Date().getTime();
Затем следует код, который вас интересует. Очевидно, что это может быть не только функция, но и блок кода, время работы которого вы хотите замерять.
Когда скрипт выполнился, нужно создать новую константу end с объектом new Date() и методом getTime(), чтоб установить конец замера времени работы кода.
const end = new Date().getTime();
Далее, простым отниманием end — start мы и получим нужную разницу в миллисекундах и теперь нам известно, сколько времени ушло на выполнение кода.
const start= new Date().getTime(); someFunction(); const end = new Date().getTime(); console.log('SecondWay: $ms');
Теперь вы знаете два наиболее простых и распространённых способа по измерению времени работы вашего кода! Первый способ подойдёт для тех, кто проверяет код в консоли лично, дебажить его. Второй способ подойдёт тем, кому неудобно выводить значения в консоль или же нужно использовать полученные данные в последующей работе.
Measure execution times in browsers & Node.js
Measuring your apps performance is very important when your code is being used in production. You should therefore know the execution time of your most frequently used functions. Modern browsers and the Node.js platform provide great APIs to measure performance. In this article, I am presenting a few selected ones using JavaScript and TypeScript code examples.
Business Logic
First of all, we need a function that mimics our business logic. To make it simple, I am using a function which will return a value after 2 seconds (2000ms):
function businessLogic(): Promisenumber> return new Promise((resolve) => setTimeout(resolve, 2000); >); >
Console Timers ( console.time )
The easiest way to print the execution time of a function to the console, is to use a console timer. Everything that has to be done, is calling console.time and console.timeEnd with the same identifier:
(async () => console.time('businessLogic'); await businessLogic(); console.timeEnd('businessLogic'); >)();
As a result, we get the execution time printed to our console in a human-readable format (can be milliseconds, seconds, or other resolutions):
High Resolution Timers ( performance.now )
If you want to customize the output of your profiling, then you can use a high resolution timer like performance.now . It will return the measured execution time in 1 millisecond increments:
(async () => const start = performance.now(); await businessLogic(); const stop = performance.now(); const inSeconds = (stop - start) / 1000; const rounded = Number(inSeconds).toFixed(3); console.log(`businessLogic: $rounded>s`); >)();
Time tracking util
// Util function to track execution time in seconds export async function trackInSeconds(fn: Function): Promisestring> const start = performance.now(); await fn(); const end = performance.now(); const inSeconds = (end - start) / 1000; return Number(inSeconds).toFixed(0); > (async () => // Your business logic const myFunction = () => return new Promise(resolve => // Function completes after 5s setTimeout(resolve, 5000); >); >; const timeInSeconds = await trackInSeconds(myFunction); console.log(`Execution took $timeInSeconds> seconds.`); >)();
Performance Hooks ( perf_hooks )
Node.js provides performance measurement APIs to profile JavaScript and TypeScript functions. With the perf_hooks module it becomes very convenient to profile multiple functions at once.
TypeScript Typings
To use the perf_hooks module with TypeScript, we have to install type definitions that match our Node.js version (I am using v14):
npm install --save @types/node@14
Performance Observer
We have seen that console.time doesn’t let us customize the output and performance.now is very difficult to control if you want to monitor several functions. That’s why Node.js provides a performance observer. The performance observer can listen to different kinds of measurements and receives entries that return the measured time in milliseconds. To make the performance collection asynchronous, the buffered flag can be used, so that multiple entries will be buffered internally:
import PerformanceObserver> from 'perf_hooks'; const observer = new PerformanceObserver(list => list.getEntries().forEach(entry => console.info(entry))); observer.observe(buffered: true, entryTypes: ['measure']>);
Performance Marks ( performance.mark )
After setting up the performance observer, we can start a measurement. The simplest way is to set markings. It works similar to the console.time approach with the difference that we need to use different labels for the start and the stop:
import performance, PerformanceObserver> from 'perf_hooks'; function businessLogic(): Promisenumber> return new Promise((resolve) => setTimeout(resolve, 2000); >); > (async () => const observer = new PerformanceObserver(list => list.getEntries().forEach(entry => console.info(entry))); observer.observe(buffered: true, entryTypes: ['measure']>); performance.mark('start'); await businessLogic(); performance.mark('stop'); performance.measure('Business Logic', 'start', 'stop'); >)();
PerformanceEntry name: 'Business Logic', entryType: 'measure', startTime: 3020.9561, duration: 2007.4025 >
Performance Instrumentation ( performance.timerify )
For more convenience, there is the performance.timerify function. It wraps new functions automatically into performance marks, so that we don’t need to declare start and stop. In that case our observer must listen to the entry type ‘function’ :
(async () => const observer = new PerformanceObserver(list => list.getEntries().forEach(entry => console.info(entry))); observer.observe(buffered: true, entryTypes: ['function']>); const wrapped = performance.timerify(businessLogic); await wrapped(); >)();
PerformanceEntry name: 'businessLogic', entryType: 'function', startTime: 2221.5801, duration: 0.6079 >
💡 As you can see, the tracked duration is different from our measurements with performance.mark . That’s because performance.timerify doesn’t work out of the box with asynchronous functions on Node.js v14. James M Snell from the Node team tweeted me that performance.timerify will work with async functions in Node v16 and above. With Node.js v14 we have to use the async_hooks module to register callbacks tracking the lifetime of asynchronous resources. There is good documentation with an example on measuring the duration of async operations.
Completion of measurement
It’s recommended to disconnect the performance observer from all incoming notifications, when you are done with your measurements:
Inclusion in Unit Tests
If you want to ensure the execution speed of your functions in the long run, you can make them part of your unit tests. Many testing frameworks (like Jest, Jasmine, and others) allow you to set a timeout for the execution of your test. The timeout feature can be used to mark a test as failed if the tested function takes too long to execute. Here is a timeout example with the Jasmine testing framework: businessLogic.ts
export function businessLogic(): Promisenumber> return new Promise((resolve) => setTimeout(resolve, 2000); >); >
import businessLogic> from './businessLogic'; describe('businessLogic', () => it('does not take longer than 3 seconds (3000ms)', async () => await businessLogic(); >, 3000); >);
Get connected 🔗
Please follow me on Twitter or subscribe to my YouTube channel if you liked this post. I would love to hear from you what you are building. 🙂 Best, Benny