From f8ecd4f2c0fe1c5751d85f5af4662130a6c4aafd Mon Sep 17 00:00:00 2001 From: Edy Silva Date: Sat, 21 Mar 2026 00:19:06 -0300 Subject: [PATCH] perf_hooks: ensure timerify records at least 1ns in histogram --- lib/internal/perf/timerify.js | 3 +- ...est-perf-hooks-timerify-histogram-sync.mjs | 38 +++++++++++++------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/internal/perf/timerify.js b/lib/internal/perf/timerify.js index f9e9b8a39d993f..4946424cd80b59 100644 --- a/lib/internal/perf/timerify.js +++ b/lib/internal/perf/timerify.js @@ -3,6 +3,7 @@ const { FunctionPrototypeBind, MathCeil, + MathMax, ObjectDefineProperties, ReflectApply, ReflectConstruct, @@ -37,7 +38,7 @@ const { function processComplete(name, start, args, histogram) { const duration = now() - start; if (histogram !== undefined) - histogram.record(MathCeil(duration * 1e6)); + histogram.record(MathMax(1, MathCeil(duration * 1e6))); const entry = createPerformanceNodeEntry( name, diff --git a/test/parallel/test-perf-hooks-timerify-histogram-sync.mjs b/test/parallel/test-perf-hooks-timerify-histogram-sync.mjs index b26a40ee3cda65..b9ecc4f31f5e16 100644 --- a/test/parallel/test-perf-hooks-timerify-histogram-sync.mjs +++ b/test/parallel/test-perf-hooks-timerify-histogram-sync.mjs @@ -4,16 +4,32 @@ import { sleepSync } from '../common/index.mjs'; import assert from 'assert'; import { createHistogram, timerify } from 'perf_hooks'; -const histogram = createHistogram(); +{ + const histogram = createHistogram(); -const m = () => { - // Deterministic blocking delay (~1 millisecond). The histogram operates on - // nanosecond precision, so this should be sufficient to prevent zero timings. - sleepSync(1); -}; -const n = timerify(m, { histogram }); -assert.strictEqual(histogram.max, 0); -for (let i = 0; i < 10; i++) { - n(); + const m = () => { + // Deterministic blocking delay (~1 millisecond). The histogram operates on + // nanosecond precision, so this should be sufficient to prevent zero timings. + sleepSync(1); + }; + const n = timerify(m, { histogram }); + assert.strictEqual(histogram.max, 0); + for (let i = 0; i < 10; i++) { + n(); + } + assert.notStrictEqual(histogram.max, 0); +} + +// Regression test for https://github.com/nodejs/node/issues/54803 +// Sub-nanosecond functions must not throw ERR_OUT_OF_RANGE. +{ + const histogram = createHistogram(); + const m = () => {}; + const n = timerify(m, { histogram }); + for (let j = 0; j < 100; j++) { + for (let i = 0; i < 1000; i++) { + n(); + } + } + assert.ok(histogram.min >= 1); } -assert.notStrictEqual(histogram.max, 0);