我正在尝试使用Benchmark.js
对对象的成员函数进行基准测试。几个因素使测试功能变得困难:
让我们说它看起来像这样:
class Something {
constructor(){
// async ops
this.expensiveValue = null;
}
expensiveOperation () {
if (this.expensiveValue === null) {
// Do expensive operation
this.expensiveValue = result; // a non-null value
}
}
}
现在,我要基准expensiveOperation
。但是由于其局限性,每次运行我还需要“重置”该对象。
据我所知,benchmark
不支持每次运行设置。我觉得将重设作为运行的一部分也不是最佳实践,因为它会污染我实际试图进行基准测试的内容。
我看过Benchmark.setup
,但这仅按周期执行,而不是按运行。
我想念什么吗?我可以使用另一个benchmark
选项吗?还是我处理方法不正确?
Benchmark.js不会在函数的每次迭代中执行setup
/ teardown
,而是仅对每个benchmark.js cycle
执行一次,通常可以在5秒内运行,这可能是数百至数千至数百万个电话。 Benchmark.js的作者在Bulletproof JavaScript benchmarks中解释说,这样做的理由非常充分。
如果您认为这些原因不适用于您,那么我会问您为什么还要使用Benchmark.js。您可以轻松编写一个循环并测量每个调用的持续时间,并用几行代码自己取平均值。您不需要精美的图书馆。
您不能总是得到想要的东西
如果您尝试尝试,可能会发现
老实说,是的,您的做法不正确。您的expensiveOperation ()
设计为对所有后续调用都有效,因此,一个好的基准当然可以反映出来。第一次通话的费用在所有后续通话中摊销。 Benchmark.js将尝试衡量方法[[按设计]]的效率。这就是重点。考虑您的基本目标,以及为什么要为每次迭代重置目标。您不想对expensiveOperation ()
作基准测试,而只对方法的这一部分进行基准测试:
// Do expensive operation
this.expensiveValue = result; // a non-null value
因此只需将其分解为方法或函数,然后对其进行基准测试。 :)
我不会接受这个答案,因为我对这个主题的知识不足,无法100%肯定,但是我确实想分享我的发现。如果应该将其移到我的问题或评论中,请使用评论ping我。