我知道正式的描述:
设置:创建测试的预期状态。
拆卸:进行必要的清理操作。
但是,为什么这是必要的,尤其是在 Benchmark.js 中?为什么需要不同的测试周期(如this文章中的Benchmark.js中所定义)? 我观察到,在我能想到的所有情况下(我也认为在所有其他情况下),您可以将设置代码移至准备代码(基准/测试之外的代码),也许将代码拆解到代码末尾,功能本质上是相同的(我也查看了一些 jsperf.com 测试,据我所知,它们也是如此)。
例如,这是我创建的基准测试,该版本使用Setups和Teardowns:
const bench = new Benchmark(
'TicTacToeBenchmark',
// The function to test
() => {
ticTacToe.addEvent(
'turn',
player => {
turnText.innerHTML =
'It\'s ' + (player['id'] === 1 ? 'X' : 'O') + '\'s turn.';
}
);
},
{
'setup': () => {
const players = [
{
char: '✕',
className: 'playerX',
id: 1,
},
{
char: '◯',
className: 'playerY',
id: 2,
},
];
const ticTacToe = new TicTacToe(3, players);
}
}
);
bench.run();
console.log(bench); // 'mean' is 5e-7 seconds
相同的示例,除了测试所需的所有内容都与页面的其余部分一起声明:
const players = [
{
char: '✕',
className: 'playerX',
id: 1,
},
{
char: '◯',
className: 'playerY',
id: 2,
},
];
const ticTacToe = new TicTacToe(3, players);
const bench = new Benchmark(
'TicTacToeBenchmark',
// The function to test
() => {
ticTacToe.addEvent(
'turn',
player => {
turnText.innerHTML =
'It\'s ' + (player['id'] === 1 ? 'X' : 'O') + '\'s turn.';
}
);
}
);
bench.run();
console.log(bench); // 'mean' is 7e-7 seconds
也许差异在单元测试中更明显?我不知道。您能否提供一些不同的情况?或者解释为什么测试必须在循环内运行的迭代中运行(本质上,就像 2 个循环,循环是外部循环)?
我在网上能找到的关于这个主题的所有内容基本上都是用不同的措辞重新表述Setup和Teardown的定义,不幸的是,这个主题没有维基百科条目。
设置和拆卸是您放置以下代码的位置:(1) 需要在要进行基准测试的函数之前或之后运行,但 (2) 不想包含在基准测试的测量中。
例如,假设您有一个文本搜索库。使用方法如下:
searchEngine = new New SearchEngine(pathToLargeCorpusOfText)
searchEngine.search(queryString)
searchEngine.close()
- 释放内存如果您想单独对
search()
方法进行基准测试,即不影响结果 (1) 和 (3),则可以分别将它们放入 setup 和teardown 中。
要准确地对函数进行基准测试,必须运行多次。 Benchmark.js 每个周期运行多次迭代(
search()
一次调用),并为每个基准运行多个周期。我无法比 Benchmark.js 的作者更好地解释其中的原因:Mathias Bynens 和 John-David Dalton 的Bulletproof JavaScript benchmarks。