我需要以毫秒为单位获取执行时间。

我最初问这个问题是在2008年。当时接受的答案是使用newDate().getTime()。然而,我们现在都可以同意使用标准performance.now()API更合适。因此,我将接受的答案改为这个答案。


当前回答

process.hrtime()在Node.js中可用-它返回以纳秒为单位的值

let hrTime = process.hrtime()
console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)

其他回答

下面是计时函数的修饰符

它包装函数,以便它们每次运行时都能计时

用法:

let test = () => { /* does something */ }
test = timed(test)   // turns the function into a timed function in one line
test()               // run your code as normal, logs 'function test took 1001.900ms' 

这是装饰者:

let timed = (f) => (...args) => {
    let start = performance.now();
    let ret = f(...args);
    console.log(`function ${f.name} took ${(performance.now() - start).toFixed(3)}ms`);
    return ret;   
}

如果您使用的是异步函数,您可以将其设置为定时异步,并在f(…args)之前添加一个await,这应该适用于这些函数。如果您希望一个装饰器同时处理同步和异步函数,则会变得更加复杂。

最好的方法是使用性能挂钩模块。虽然不稳定,但您可以标记代码的特定区域,并测量标记区域之间的持续时间。

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

const measures = []

const obs = new PerformanceObserver(list => measures.push(...list.getEntries()));
obs.observe({ entryTypes: ['measure'] });
const getEntriesByType = cb => cb(measures);

const doSomething = val => {
  performance.mark('beginning of the process');

  val *= 2;

  performance.mark('after multiplication');

  performance.measure('time taken', 'beginning of the process', 'after multiplication');

  getEntriesByType(entries => {
    entries.forEach(entry => console.log(entry));
  })

  return val;
}

doSomething(4);

在此处尝试

process.hrtime()在Node.js中可用-它返回以纳秒为单位的值

let hrTime = process.hrtime()
console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)

具有累积循环的秒表

与服务器和客户端(节点或DOM)一起工作,使用Performance API。当您有许多小循环时(例如,在处理1000个数据对象的调用1000次的函数中)很好,但您希望了解该函数中的每个操作如何相加。

所以这一个使用了模块全局(singleton)计时器。与类单例模式相同,只是使用起来稍微简单一点,但您需要将其放在一个单独的例如秒表.js文件中。

const perf = typeof performance !== "undefined" ? performance : require('perf_hooks').performance;
const DIGITS = 2;

let _timers = {};

const _log = (label, delta?) => {
    if (_timers[label]) {
        console.log(`${label}: ` + (delta ? `${delta.toFixed(DIGITS)} ms last, ` : '') +
            `${_timers[label].total.toFixed(DIGITS)} ms total, ${_timers[label].cycles} cycles`);
    }
};

export const Stopwatch = {
    start(label) {
        const now = perf.now();
        if (_timers[label]) {
            if (!_timers[label].started) {
                _timers[label].started = now;
            }
        } else {
            _timers[label] = {
                started: now,
                total: 0,
                cycles: 0
            };
        }
    },
    /** Returns total elapsed milliseconds, or null if stopwatch doesn't exist. */
    stop(label, log = false) {
        const now = perf.now();
        if (_timers[label]) {
            let delta;
            if(_timers[label].started) {
                delta = now - _timers[label].started;
                _timers[label].started = null;
                _timers[label].total += delta;
                _timers[label].cycles++;
            }
            log && _log(label, delta);
            return _timers[label].total;
        } else {
            return null;
        }
    },
    /** Logs total time */
    log: _log,
    delete(label) {
        delete _timers[label];
    }
};

注意:纯函数ES6方法的最简单实现,无需额外变量,只需3行代码。处理同步和异步代码,因此不需要外部库,可以在JavaScript和NodeJS中工作,甚至可以用来测试API的延迟

// Create one-liner timer function
let [timer, timingMonitor] = [0, () => timer = !timer ? Date.now() : `${Date.now() - timer}ms`]
        
// Initiate timer
timingMonitor();
        
// Your code here
doSomething();
        
// Capture and store the elapsed time 
const timeElapsed = timingMonitor();

console.log(timeElapsed);
// Console output: "102ms", for example