我想做以下事情:
console.time("processA");
for(let i; i < 10000; i++) {
// Just to simulate the process
}
console.timeEnd("processA");
但我想捕获时间结束并使用我自己的信息记录器。
是否可以处理timeEnd的控制台输出?
如何测量nodejs中进程的时间间隔?
由于您的目标是 Nodejs,因此可以使用
process.hrtime
,如 docs 中所述
process.hrtime()方法以[秒,纳秒]元组数组形式返回当前高分辨率实时,其中纳秒是实时中无法以秒精度表示的剩余部分。
因此您可以测量高达纳秒的计时,这是
console.time
无法测量的,正如您在示例中看到的 console.time
或 Date
差异测量 0 秒。
例如:
const NS_PER_SEC = 1e9;
const MS_PER_NS = 1e-6
const time = process.hrtime();
for (let i; i < 10000; i++) {
// Just to simulate the process
}
const diff = process.hrtime(time);
console.log(`Benchmark took ${diff[0] * NS_PER_SEC + diff[1]} nanoseconds`);
console.log(`Benchmark took ${ (diff[0] * NS_PER_SEC + diff[1]) * MS_PER_NS } milliseconds`);
从 Node v8.5 开始,您可以使用浏览器等效的
performance.now()
,它比 process.hrtime
更容易使用,因为它直接以毫秒为单位输出时间,因此您不必像 process.hrtime
中那样进行转换
const { performance } = require("perf_hooks");
const start = performance.now();
doSomething();
const end = performance.now();
console.log(`time taken: ${end - start}ms`);
您可以从性能 API 上的 Node.js 文档找到更多信息。
由于我在多个地方使用计时器,所以我根据Alex的回答编写了一个简单的类:
const t = new Timer('For Loop')
// your code
t.runtimeMs() // => 1212.34
t.runtimeMsStr() // => 'For Loop took 1232.34 milliseconds'
代码如下:
class Timer {
// Automatically starts the timer
constructor(name = 'Benchmark') {
this.NS_PER_SEC = 1e9;
this.MS_PER_NS = 1e-6
this.name = name;
this.startTime = process.hrtime();
}
// returns the time in ms since instantiation
// can be called multiple times
runtimeMs() {
const diff = process.hrtime(this.startTime);
return (diff[0] * this.NS_PER_SEC + diff[1]) * this.MS_PER_NS;
}
// retuns a string: the time in ms since instantiation
runtimeMsStr() {
return `${this.name} took ${this.runtimeMs()} milliseconds`;
}
}
var startTime = new Date();
for(let i; i < 10000; i++) {
// Just to simulate the process
}
var endTime = new Date() - startTime;
您将获得完成操作所需的总时间
要使用 Node.js 性能 API 构建 Deepal 的答案,您还可以使用
performance.mark()
,它允许您在代码中任何感兴趣的点提供命名标记。
以下示例说明在循环内创建实例“Foo”如何影响日志记录的执行。
import { performance } from "perf_hooks";
const INSTANCES = 1000;
class Foo {
constructor(name) {
this.name = name;
}
log() {
this.message_to_log = 'Logger test: ' + this.name;
}
}
// Creation of Foo instances inside a foor loop :(
function start() {
for(let i = 0; i < INSTANCES; i++) {
const foo = new Foo();
foo.log();
}
}
performance.mark("mark_foologger_start");
start();
performance.mark("mark_foologger_end");
// Logging without creation of instances inside for loop
function startImproved(foos) {
for(let i = 0, length = foos.length; i < length; i++) {
foos[i].log();
}
}
const fooInstances = [];
for(let i = 0; i < INSTANCES; i++) {
fooInstances.push(new Foo(`Logger ${i}`));
}
performance.mark("mark_foologgerimproved_start");
startImproved(fooInstances);
performance.mark("mark_foologgerimproved_end");
console.log('Timeline of the performance get entries');
console.log(performance.getEntries());
console.log('Results on the foo logger duration with creation of new instances inside loop');
console.log(
performance.measure(
"measure_foologger_perf",
"mark_foologger_start",
"mark_foologger_end"
)
);
console.log('Results on the foo logger duration without creation of new instances inside loop');
console.log(
performance.measure(
"measure_foologger_perf",
"mark_foologgerimproved_start",
"mark_foologgerimproved_end"
)
);
duration
显示两个标记之间的差异(以毫秒为单位)。
使用
performance.mark()
的一个优点是这些标记会添加到表演时间线中,这样您就可以使用 performance.getEntries()
或 PerformanceObserver
检索它们。
这里是时间线和每个案例持续时间的日志:
Timeline of the performance get entries
[
PerformanceMark {
name: 'mark_foologger_start',
entryType: 'mark',
startTime: 19.05731000006199,
duration: 0,
detail: null
},
PerformanceMark {
name: 'mark_foologger_end',
entryType: 'mark',
startTime: 19.334975000470877,
duration: 0,
detail: null
},
PerformanceMark {
name: 'mark_foologgerimproved_start',
entryType: 'mark',
startTime: 19.490791000425816,
duration: 0,
detail: null
},
PerformanceMark {
name: 'mark_foologgerimproved_end',
entryType: 'mark',
startTime: 19.587886000052094,
duration: 0,
detail: null
}
]
Results on the foo logger duration with creation of new instances inside loop
PerformanceMeasure {
name: 'measure_foologger_perf',
entryType: 'measure',
startTime: 19.05731000006199,
duration: 0.27766500040888786
}
Results on the foo logger duration without creation of new instances inside loop
PerformanceMeasure {
name: 'measure_foologger_perf',
entryType: 'measure',
startTime: 19.490791000425816,
duration: 0.09709499962627888
}
看这里https://alligator.io/js/console-time-timeend/
var begin=console.time('t');
for(let i; i < 100000; i++) {
// Just to simulate the process
}
var end= console.timeEnd('t');
var timeSpent=(end-begin) / 1000 + "secs";