使用 Node Js 测量处理时间?

问题描述 投票:0回答:6

我想做以下事情:

console.time("processA");
for(let i; i < 10000; i++) {
// Just to simulate the process
}
console.timeEnd("processA");

但我想捕获时间结束并使用我自己的信息记录器。

是否可以处理timeEnd的控制台输出?

如何测量nodejs中进程的时间间隔?

javascript node.js performance
6个回答
20
投票

由于您的目标是 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`);

12
投票

从 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 文档找到更多信息。


5
投票

由于我在多个地方使用计时器,所以我根据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`;
    }
}


3
投票
var startTime = new Date();
for(let i; i < 10000; i++) {
// Just to simulate the process
}
var endTime = new Date() - startTime;

您将获得完成操作所需的总时间


1
投票

要使用 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
}


0
投票

看这里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";

© www.soinside.com 2019 - 2024. All rights reserved.