每次我的基准测试代码为 运行(不仅仅是每个周期)时,如何让 Benchmark.js 执行 setup/teardown?
How to get Benchmark.js to do setup/teardown each time my benchmarked code is run (not just each cycle)?
我正在尝试使用 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
。但是由于其限制,我还需要"reset"对象每个运行。
据我所知,benchmark
不支持每 运行 设置。我觉得让 运行 的重置部分也不是最佳实践,因为它污染了我实际尝试进行基准测试的内容。
我查看了 Benchmark.setup
,但它只在每个周期执行,而不是每个 运行。
我错过了什么吗?我可以使用另一个 benchmark
选项吗?还是我处理不当?
我不会接受这个答案,因为我对这个问题的了解还不够 100% 肯定,但我确实想分享我的发现。如果这应该移到我的问题或评论中,请给我发评论。
我 认为 这不可能的原因是 Benchmark.js 执行计时的方式。
从我读过的内容(包括文本和代码)来看,Benchmark 不会计时和汇总单个 运行s,而是计算完成了多少 运行s在指定的时间内(默认 = 5 秒)。这避免了某些问题,例如低精度 timers/timestamps、运行 时间优化和浮点舍入错误。
因此,由于这些原因,它不能简单地减去执行每个 运行 设置函数所需的时间。它也无法暂停其计时器以允许执行每个 运行 设置。
由于这些原因,Benchmark.js 似乎不支持每个 运行 设置函数,因为这样做会在其工作中投入过多的扳手并降低计时精度。
你不能总是得到你想要的...♩
Benchmark.js 不会在您的函数的每次迭代中执行 setup
/teardown
,而只会针对每个 benchmark.js cycle
,这通常是它可以在 5 秒内 运行,这可能是数百到数千到数百万次调用。正如 Bulletproof JavaScript benchmarks.
中 Benchmark.js 的作者所解释的那样,它这样做是有充分理由的
如果您认为这些原因不适用于您,那么我会问您为什么还要使用 Benchmark.js。您可以轻松地编写一个循环并测量每次调用的持续时间,然后自己在几行代码中取平均值。你不需要花哨的图书馆。
你不能总是得到你想要的
如果你找个时间试试,你可能会发现
您得到 ♫ 您需要的。 ♬♪
老实说,是的,您的处理方式不正确。您的 expensiveOperation ()
旨在为所有后续调用提供高效,因此一个好的基准当然应该反映这一点。第一次通话的费用分摊到所有后续通话中。 Benchmark.js 将按照设计 尝试衡量您的方法的效率。就是这个意思。
想想你的基本目标,以及你为什么要为每次迭代重置。您不想对 expensiveOperation ()
进行基准测试,而只想对方法的这一部分进行基准测试:
// Do expensive operation
this.expensiveValue = result; // a non-null value
因此,只需将其分解为一个方法或函数,然后对其进行基准测试。 :)
我正在尝试使用 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
。但是由于其限制,我还需要"reset"对象每个运行。
据我所知,benchmark
不支持每 运行 设置。我觉得让 运行 的重置部分也不是最佳实践,因为它污染了我实际尝试进行基准测试的内容。
我查看了 Benchmark.setup
,但它只在每个周期执行,而不是每个 运行。
我错过了什么吗?我可以使用另一个 benchmark
选项吗?还是我处理不当?
我不会接受这个答案,因为我对这个问题的了解还不够 100% 肯定,但我确实想分享我的发现。如果这应该移到我的问题或评论中,请给我发评论。
我 认为 这不可能的原因是 Benchmark.js 执行计时的方式。
从我读过的内容(包括文本和代码)来看,Benchmark 不会计时和汇总单个 运行s,而是计算完成了多少 运行s在指定的时间内(默认 = 5 秒)。这避免了某些问题,例如低精度 timers/timestamps、运行 时间优化和浮点舍入错误。
因此,由于这些原因,它不能简单地减去执行每个 运行 设置函数所需的时间。它也无法暂停其计时器以允许执行每个 运行 设置。
由于这些原因,Benchmark.js 似乎不支持每个 运行 设置函数,因为这样做会在其工作中投入过多的扳手并降低计时精度。
你不能总是得到你想要的...♩
Benchmark.js 不会在您的函数的每次迭代中执行 setup
/teardown
,而只会针对每个 benchmark.js cycle
,这通常是它可以在 5 秒内 运行,这可能是数百到数千到数百万次调用。正如 Bulletproof JavaScript benchmarks.
如果您认为这些原因不适用于您,那么我会问您为什么还要使用 Benchmark.js。您可以轻松地编写一个循环并测量每次调用的持续时间,然后自己在几行代码中取平均值。你不需要花哨的图书馆。
你不能总是得到你想要的
如果你找个时间试试,你可能会发现
您得到 ♫ 您需要的。 ♬♪
老实说,是的,您的处理方式不正确。您的 expensiveOperation ()
旨在为所有后续调用提供高效,因此一个好的基准当然应该反映这一点。第一次通话的费用分摊到所有后续通话中。 Benchmark.js 将按照设计 尝试衡量您的方法的效率。就是这个意思。
想想你的基本目标,以及你为什么要为每次迭代重置。您不想对 expensiveOperation ()
进行基准测试,而只想对方法的这一部分进行基准测试:
// Do expensive operation
this.expensiveValue = result; // a non-null value
因此,只需将其分解为一个方法或函数,然后对其进行基准测试。 :)