我正在尝试编写一个函数来测量另一个函数的执行时间:
export class Profiler {
public measureSyncFunc(fn: () => any): Promise<number> {
return new Promise<number>((resolve, reject) => {
let elapsed = 0;
let intervalId = window.setInterval(() => {
elapsed += 1; // this is never called
}, 1);
this.execFunc(fn)
.then((result: any) => {
window.clearInterval(intervalId);
resolve(elapsed);
});
});
}
private execFunc(fn: () => any): Promise<any> {
return new Promise<any>((resolve, reject) => {
resolve(fn());
});
}
}
然后我这样使用它:
let array = generateRandomArray(100000);
instance.measureSyncFunc(bubbleSort(array))
.then((elapsed: number) => {
console.log(`end session: ${elapsed} seconds`);
resolve();
});
bubbleSort函数是同步的,需要几秒钟才能完成。请参阅代码here:
控制台中的结果是“结束会话:0秒”,因为从未调用间隔回调。
你知道我怎么叫它吗?非常感谢你们!
5条答案
按热度按时间z9smfwbn1#
如果你想要测量的函数总是同步的,那么就真的没有必要涉及承诺。
由于您要测试的函数需要参数,因此最好将其 Package 在一个箭头函数中,以便能够使用另一个上下文调用它,而不必自己管理它的参数。
像这样简单的东西就可以了。
如果你想测量一个异步函数(如果它返回一个promise)解析所花费的时间,你可以很容易地把代码修改成这样:
注:此解决方案使用ES6 Promise,如果您使用其他解决方案,则可能需要对其进行调整,但逻辑应该相同。
你可以看到两个例子都在这里的操场上工作。
ybzsozfc2#
不要使用
setInterval
来计算毫秒数(它是inaccurate、lags、drifts,最小间隔大约为4ms),只需获取执行前后的两个时间戳。为了获得更高的精度,请将
Date.now
替换为performance.now
。8nuwlpux3#
看一下timeFnPromise和相关的test cases。
示例用法:
也可通过NPM模块jschest获得。
vjrehmav4#
这是我写的一个简单的 Package 函数。它返回一个Promise(通过async关键字),所以你可以用你的Promise调用它。我把时间值作为一个属性添加到响应中。如果你不能在响应中有这个值,那么你需要在以后删除它。
rslzwgfq5#
toskv提出的方法只适用于单个promise的解析,如果我们想使用Promise.all(),它返回的时间结果是错误的。
下面是一个由toskv开发的代码示例,但是使用Promise.all()
承诺衡量.all()
如果有人需要测量执行Promise.all()中的每个承诺所花费的时间,可以采用的方法是使用拦截器并在那里进行时间测量