Spec-Zone.ru › Node.js 14 LTS

API измерения производительности

Устойчивость: 2 - Стабильно

Исходный код: lib/perf_hooks.js

Этот модуль предоставляет реализацию подмножества API производительности веб-страниц W3C Web Performance APIs, а также дополнительные API для измерений производительности, специфичных для Node.js.

Node.js поддерживает следующие API производительности веб-страниц:

  • Высокоточная синхронизация
  • Временная шкала производительности
  • Измерение времени работы пользователя
const { PerformanceObserver, performance } = require('perf_hooks');

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration);
  performance.clearMarks();
});
obs.observe({ entryTypes: ['measure'] });
performance.measure('Start to Now');

performance.mark('A');
doSomeLongRunningProcess(() => {
  performance.measure('A to Now', 'A');

  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
});

perf_hooks.performance

Добавлен в: v8.5.0

Объект, который можно использовать для сбора метрик производительности текущего экземпляра Node.js. Он похож на window.performance в браузерах.

performance.clearMarks([name])

Добавлен в: v8.5.0
  • name <строка>

Если name не указан, удаляет все объекты PerformanceMark из временной шкалы производительности. Если name указан, удаляет только метку с указанным именем.

performance.eventLoopUtilization([utilization1[, utilization2]])

Добавлен в: v14.10.0, v12.19.0
  • utilization1 <объект> Результат предыдущего вызова eventLoopUtilization().
  • utilization2 <объект> Результат предыдущего вызова eventLoopUtilization() до utilization1.
  • Возвращает <объект>
    • idle <число>
    • active <число>
    • utilization <число>

Метод eventLoopUtilization() возвращает объект, содержащий суммарную продолжительность времени, в течение которого цикл событий был как простаивал, так и активен, как таймер с высокой точностью в миллисекундах. Значение utilization — это вычисленная загрузка цикла событий (ELU).

Если запуск на основном потоке еще не завершен, свойства имеют значение 0. ELU немедленно доступна в потоках-работниках, так как запуск происходит внутри цикла событий.

И utilization1, и utilization2 — необязательные параметры.

Если utilization1 передан, тогда вычисляется разница между текущим вызовом active и idle временем, а также соответствующее значение utilization (подобно process.hrtime()).

Если utilization1 и utilization2 оба переданы, тогда вычисляется разница между двумя аргументами. Это удобный вариант, потому что, в отличие от process.hrtime(), вычисление ELU более сложно, чем простое вычитание.

ELU похожа на загрузку ЦП, но она измеряет только статистику цикла событий, а не использование ЦП. Она представляет собой процент времени, затраченного циклом событий вне поставщика событий цикла событий (например, epoll_wait). Другое время простоя ЦП не учитывается. Следующий пример показывает, как у процесса, в основном простаивающего, будет высокая ELU.

'use strict';
const { eventLoopUtilization } = require('perf_hooks').performance;
const { spawnSync } = require('child_process');

setImmediate(() => {
  const elu = eventLoopUtilization();
  spawnSync('sleep', ['5']);
  console.log(eventLoopUtilization(elu).utilization);
});

Хотя ЦП в основном простаивает во время выполнения этого скрипта, значение utilization равно 1. Это связано с тем, что вызов child_process.spawnSync() блокирует цикл событий, не позволяя ему продолжить работу.

Передача пользовательского объекта вместо результата предыдущего вызова eventLoopUtilization() приведет к неопределенному поведению. Возвращаемые значения не гарантируют отражения правильного состояния цикла событий.

performance.mark([name])

Добавлен в: v8.5.0
  • name <строка>

Создает новую запись PerformanceMark во временной шкале производительности. PerformanceMark — подкласс PerformanceEntry, чьё значение performanceEntry.entryType всегда 'mark', а чьё значение performanceEntry.duration всегда 0. Метки производительности используются для маркирования конкретных значительных моментов во временной шкале производительности.

performance.measure(name[, startMark[, endMark]])

История
Версия Изменения
v14.0.0

Параметры startMark и endMark сделаны необязательными.

v8.5.0

Добавлен в: v8.5.0

  • name <строка>
  • startMark <строка> Необязательно.
  • endMark <строка> Необязательно.

Создает новую запись PerformanceMeasure во временной шкале производительности. PerformanceMeasure — подкласс PerformanceEntry, чьё значение performanceEntry.entryType всегда 'measure', а чьё значение performanceEntry.duration измеряет количество миллисекунд, прошедших с момента startMark и endMark.

Аргумент startMark может идентифицировать любую существующую PerformanceMark во временной шкале производительности или может идентифицировать любое из свойств временных меток, предоставляемых классом PerformanceNodeTiming. Если указанная startMark не существует, то startMark устанавливается в значение timeOrigin по умолчанию.

Необязательный аргумент endMark должен идентифицировать любую существующую PerformanceMark во временной шкале производительности или любое из свойств временных меток, предоставляемых классом PerformanceNodeTiming. endMark будет иметь значение performance.now(), если параметр не передан; в противном случае, если указанная endMark не существует, будет выброшено исключение.

performance.nodeTiming

Добавлен в: v8.5.0
  • <PerformanceNodeTiming>

Это свойство является расширением Node.js. Оно недоступно в веб-браузерах.

Экземпляр класса PerformanceNodeTiming, который предоставляет метрики производительности для конкретных вех Node.js.

performance.now()

Добавлен в: v8.5.0
  • Возвращает: <число>

Возвращает текущую высокую временную метку миллисекунд, где 0 представляет начало текущего node процесса.

performance.timeOrigin

Добавлен в: v8.5.0
  • <число>

Значение timeOrigin указывает на временную метку миллисекунд с высокой точностью, в момент начала текущего node процесса, измеренную в временной шкале Unix.

performance.timerify(fn)

Добавлен в: v8.5.0
  • fn <функция>

Это свойство является расширением Node.js. Оно недоступно в веб-браузерах.

Оборачивает функцию новой функцией, которая измеряет время выполнения обернутой функции. PerformanceObserver должно быть подписано на тип события 'function', чтобы получить доступ к деталям измерения времени.

const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

function someFunction() {
  console.log('hello world');
}

const wrapped = performance.timerify(someFunction);

const obs = new PerformanceObserver((list) => {
  console.log(list.getEntries()[0].duration);
  obs.disconnect();
});
obs.observe({ entryTypes: ['function'] });

// A performance timeline entry will be created
wrapped();

Класс: PerformanceEntry

Добавлена в: v8.5.0

performanceEntry.duration

Добавлена в: v8.5.0
  • <число>

Общее количество миллисекунд, прошедших для этой записи. Это значение не будет иметь смысла для всех типов записей Performance.

performanceEntry.entryType

Добавлена в: v8.5.0
  • <строка>

Тип записи производительности. Может быть одним из:

  • 'node' (только Node.js)
  • 'mark' (доступно в браузере)
  • 'measure' (доступно в браузере)
  • 'gc' (только Node.js)
  • 'function' (только Node.js)
  • 'http2' (только Node.js)
  • 'http' (только Node.js)

performanceEntry.flags

Добавлена в: v13.9.0, v12.17.0
  • <число>

Это свойство расширение Node.js. Оно недоступно в веб-браузерах.

Когда performanceEntry.entryType равно 'gc', свойство performance.flags содержит дополнительную информацию об операции сборки мусора. Значение может быть одним из:

  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_NO
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_FORCED
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY
  • perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE

performanceEntry.name

Добавлена в: v8.5.0
  • <строка>

Имя записи производительности.

performanceEntry.kind

Добавлена в: v8.5.0
  • <число>

Это свойство расширение Node.js. Оно недоступно в веб-браузерах.

Когда performanceEntry.entryType равно 'gc', свойство performance.kind идентифицирует тип операции сборки мусора, которая произошла. Значение может быть одним из:

  • perf_hooks.constants.NODE_PERFORMANCE_GC_MAJOR
  • perf_hooks.constants.NODE_PERFORMANCE_GC_MINOR
  • perf_hooks.constants.NODE_PERFORMANCE_GC_INCREMENTAL
  • perf_hooks.constants.NODE_PERFORMANCE_GC_WEAKCB

performanceEntry.startTime

Добавлена в: v8.5.0
  • <число>

Отметка времени в миллисекундах с высоким разрешением, обозначающая начальное время записи производительности.

Класс: PerformanceNodeTiming

Добавлена в: v8.5.0
  • Расширяет: <PerformanceEntry>

Это свойство расширение Node.js. Оно недоступно в веб-браузерах.

Предоставляет сведения о времени выполнения самого Node.js. Конструктор этого класса не доступен пользователям.

performanceNodeTiming.bootstrapComplete

Добавлена в: v8.5.0
  • <число>

Отметка времени в миллисекундах с высоким разрешением, в которой процесс Node.js завершил загрузку. Если загрузка ещё не завершена, свойство имеет значение -1.

performanceNodeTiming.environment

Добавлена в: v8.5.0
  • <число>

Отметка времени в миллисекундах с высоким разрешением, в которой была инициализирована среда Node.js.

performanceNodeTiming.idleTime

Добавлена в: v14.10.0, v12.19.0
  • <число>

Отметка времени в миллисекундах с высоким разрешением, указывающая, сколько времени цикл событий был неактивен в поставщике событий цикла событий (например, epoll_wait). Это не учитывает использование ЦП. Если цикл событий ещё не запущен (например, в первом цикле основного скрипта), свойство имеет значение 0.

performanceNodeTiming.loopExit

Добавлена в: v8.5.0
  • <число>

Отметка времени в миллисекундах с высоким разрешением, в которой Node.js цикл событий завершился. Если цикл событий ещё не завершен, свойство имеет значение -1. Оно может иметь значение, отличное от -1, только в обработчике события 'exit'.

performanceNodeTiming.loopStart

Добавлена в: v8.5.0
  • <число>

Отметка времени в миллисекундах с высоким разрешением, в которой начался цикл событий Node.js. Если цикл событий ещё не начался (например, в первом цикле основного скрипта), свойство имеет значение -1.

performanceNodeTiming.nodeStart

Добавлена в: v8.5.0
  • <число>

Отметка времени в миллисекундах с высоким разрешением, в которой был инициализирован процесс Node.js.

performanceNodeTiming.v8Start

Добавлена в: v8.5.0
  • <число>

Отметка времени в миллисекундах с высоким разрешением, в которой была инициализирована платформа V8.

Класс: perf_hooks.PerformanceObserver

new PerformanceObserver(callback)

Добавлена в: v8.5.0
  • callback <Функция>
    • list <PerformanceObserverEntryList>
    • observer <PerformanceObserver>

Объекты PerformanceObserver предоставляют уведомления, когда новые экземпляры PerformanceEntry добавлены в временную шкалу производительности.

const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

const obs = new PerformanceObserver((list, observer) => {
  console.log(list.getEntries());
  observer.disconnect();
});
obs.observe({ entryTypes: ['mark'], buffered: true });

performance.mark('test');

Поскольку экземпляры PerformanceObserver вводят свой дополнительный накладные расходы на производительность, экземпляры не должны подписываться на уведомления постоянно. Пользователи должны отключать наблюдатели, как только они больше не нужны.

Функция callback вызывается, когда PerformanceObserver получает уведомление о новых экземплярах PerformanceEntry. Обработчик получает экземпляр PerformanceObserverEntryList и ссылку на экземпляр PerformanceObserver.

performanceObserver.disconnect()

Добавлена в: v8.5.0

Отключает экземпляр PerformanceObserver от всех уведомлений.

performanceObserver.observe(options)

Добавлена в: v8.5.0
  • options <Объект>
    • entryTypes <массив строк> Массив строк, определяющих типы экземпляров PerformanceEntry , которые интересуют наблюдателя. Если не указан, будет выброшено исключение.
    • buffered <логическое значение> Если true, обратный вызов уведомления будет вызван асинхронно, и уведомления о нескольких экземплярах PerformanceEntry будут буферизованы внутри. Если false, уведомления будут мгновенными и синхронными. По умолчанию: false.

Подписывает экземпляр PerformanceObserver на уведомления о новых экземплярах PerformanceEntry, идентифицированных по options.entryTypes.

Когда options.buffered является false, callback будет вызван один раз для каждого экземпляра PerformanceEntry.

const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

const obs = new PerformanceObserver((list, observer) => {
  // Called three times synchronously. `list` contains one item.
});
obs.observe({ entryTypes: ['mark'] });

for (let n = 0; n < 3; n++)
  performance.mark(`test${n}`);
const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

const obs = new PerformanceObserver((list, observer) => {
  // Called once. `list` contains three items.
});
obs.observe({ entryTypes: ['mark'], buffered: true });

for (let n = 0; n < 3; n++)
  performance.mark(`test${n}`);

Класс: PerformanceObserverEntryList

Добавлен в: v8.5.0

Класс PerformanceObserverEntryList используется для доступа к экземплярам PerformanceEntry, переданным в PerformanceObserver. Конструктор этого класса не доступен пользователю.

performanceObserverEntryList.getEntries()

Добавлен в: v8.5.0
  • Возвращает: <PerformanceEntry[]>

Возвращает список объектов PerformanceEntry в хронологическом порядке относительно performanceEntry.startTime.

const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

const obs = new PerformanceObserver((perfObserverList, observer) => {
  console.log(perfObserverList.getEntries());
  /**
   * [
   *   PerformanceEntry {
   *     name: 'test',
   *     entryType: 'mark',
   *     startTime: 81.465639,
   *     duration: 0
   *   },
   *   PerformanceEntry {
   *     name: 'meow',
   *     entryType: 'mark',
   *     startTime: 81.860064,
   *     duration: 0
   *   }
   * ]
   */
  observer.disconnect();
});
obs.observe({ entryTypes: ['mark'], buffered: true });

performance.mark('test');
performance.mark('meow');

performanceObserverEntryList.getEntriesByName(name[, type])

Добавлен в: v8.5.0
  • name <строка>
  • type <строка>
  • Возвращает: <PerformanceEntry[]>

Возвращает список объектов PerformanceEntry в хронологическом порядке относительно performanceEntry.startTime, чьё поле performanceEntry.name равно name, и необязательно, чьё поле performanceEntry.entryType равно type.

const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

const obs = new PerformanceObserver((perfObserverList, observer) => {
  console.log(perfObserverList.getEntriesByName('meow'));
  /**
   * [
   *   PerformanceEntry {
   *     name: 'meow',
   *     entryType: 'mark',
   *     startTime: 98.545991,
   *     duration: 0
   *   }
   * ]
   */
  console.log(perfObserverList.getEntriesByName('nope')); // []

  console.log(perfObserverList.getEntriesByName('test', 'mark'));
  /**
   * [
   *   PerformanceEntry {
   *     name: 'test',
   *     entryType: 'mark',
   *     startTime: 63.518931,
   *     duration: 0
   *   }
   * ]
   */
  console.log(perfObserverList.getEntriesByName('test', 'measure')); // []
  observer.disconnect();
});
obs.observe({ entryTypes: ['mark', 'measure'], buffered: true });

performance.mark('test');
performance.mark('meow');

performanceObserverEntryList.getEntriesByType(type)

Добавлен в: v8.5.0
  • type <строка>
  • Возвращает: <PerformanceEntry[]>

Возвращает список объектов PerformanceEntry в хронологическом порядке относительно performanceEntry.startTime, чьё поле performanceEntry.entryType равно type.

const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

const obs = new PerformanceObserver((perfObserverList, observer) => {
  console.log(perfObserverList.getEntriesByType('mark'));
  /**
   * [
   *   PerformanceEntry {
   *     name: 'test',
   *     entryType: 'mark',
   *     startTime: 55.897834,
   *     duration: 0
   *   },
   *   PerformanceEntry {
   *     name: 'meow',
   *     entryType: 'mark',
   *     startTime: 56.350146,
   *     duration: 0
   *   }
   * ]
   */
  observer.disconnect();
});
obs.observe({ entryTypes: ['mark'], buffered: true });

performance.mark('test');
performance.mark('meow');

perf_hooks.monitorEventLoopDelay([options])

Добавлен в: v11.10.0
  • options <Объект>
    • resolution <число> Частота выборки в миллисекундах. Должно быть больше нуля. По умолчанию: 10.
  • Возвращает: <Гистограмма>

Это свойство расширение Node.js. Оно недоступно в браузерах.

Создаёт объект Histogram для отслеживания и отчёта о задержке цикла событий со временем. Задержки будут сообщаться в наносекундах.

Использование таймера для определения приблизительной задержки цикла событий работает, потому что выполнение таймеров привязано к жизненному циклу цикла событий libuv. То есть, задержка в цикле вызовет задержку в выполнении таймера, и именно эти задержки предназначены для обнаружения этим API.

const { monitorEventLoopDelay } = require('perf_hooks');
const h = monitorEventLoopDelay({ resolution: 20 });
h.enable();
// Do something.
h.disable();
console.log(h.min);
console.log(h.max);
console.log(h.mean);
console.log(h.stddev);
console.log(h.percentiles);
console.log(h.percentile(50));
console.log(h.percentile(99));

Класс: Histogram

Добавлен в: v11.10.0

Отслеживает задержку цикла событий с заданной частотой выборки. Конструктор этого класса недоступен пользователю.

Это свойство расширение Node.js. Оно недоступно в браузерах.

histogram.disable()
Добавлен в: v11.10.0
  • Возвращает: <логическое значение>

Отключает таймер отбора проб задержки цикла событий. Возвращает true, если таймер остановлен, false, если он уже остановлен.

histogram.enable()
Добавлен в: v11.10.0
  • Возвращает: <логическое значение>

Включает таймер отбора проб задержки цикла событий. Возвращает true, если таймер запущен, false, если он уже запущен.

histogram.exceeds
Добавлен в: v11.10.0
  • <число>

Количество раз, когда задержка цикла событий превысила максимальный порог задержки цикла событий в 1 час.

histogram.max
Добавлен в: v11.10.0
  • <число>

Максимальная зарегистрированная задержка цикла событий.

histogram.mean
Добавлен в: v11.10.0
  • <число>

Среднее значение зарегистрированных задержек цикла событий.

histogram.min
Добавлен в: v11.10.0
  • <число>

Минимальная зарегистрированная задержка цикла событий.

histogram.percentile(percentile)
Добавлен в: v11.10.0
  • percentile <число> Значение процентиля в диапазоне (0, 100].
  • Возвращает: <число>

Возвращает значение в заданном процентиле.

histogram.percentiles
Добавлен в: v11.10.0
  • <Карта>

Возвращает объект Map, содержащий детали накопленного распределения процентилей.

histogram.reset()
Добавлен в: v11.10.0

Сбрасывает собранные данные гистограммы.

histogram.stddev
Добавлен в: v11.10.0
  • <число>

Среднеквадратическое отклонение зарегистрированных задержек цикла событий.

Примеры

Измерение продолжительности асинхронных операций

В следующем примере используются Async Hooks и Performance API для измерения фактической продолжительности операции Timeout (включая время выполнения обратного вызова).

'use strict';
const async_hooks = require('async_hooks');
const {
  performance,
  PerformanceObserver
} = require('perf_hooks');

const set = new Set();
const hook = async_hooks.createHook({
  init(id, type) {
    if (type === 'Timeout') {
      performance.mark(`Timeout-${id}-Init`);
      set.add(id);
    }
  },
  destroy(id) {
    if (set.has(id)) {
      set.delete(id);
      performance.mark(`Timeout-${id}-Destroy`);
      performance.measure(`Timeout-${id}`,
                          `Timeout-${id}-Init`,
                          `Timeout-${id}-Destroy`);
    }
  }
});
hook.enable();

const obs = new PerformanceObserver((list, observer) => {
  console.log(list.getEntries()[0]);
  performance.clearMarks();
  observer.disconnect();
});
obs.observe({ entryTypes: ['measure'], buffered: true });

setTimeout(() => {}, 1000);

Измерение времени загрузки зависимостей

В следующем примере измеряется продолжительность операций require() для загрузки зависимостей:

'use strict';
const {
  performance,
  PerformanceObserver
} = require('perf_hooks');
const mod = require('module');

// Monkey patch the require function
mod.Module.prototype.require =
  performance.timerify(mod.Module.prototype.require);
require = performance.timerify(require);

// Activate the observer
const obs = new PerformanceObserver((list) => {
  const entries = list.getEntries();
  entries.forEach((entry) => {
    console.log(`require('${entry[0]}')`, entry.duration);
  });
  obs.disconnect();
});
obs.observe({ entryTypes: ['function'], buffered: true });

require('some-module');

© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v14.x/docs/api/perf_hooks.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API