JSPerf 测试结果随着测试 运行 变慢?
JSPerf test results get slower as the tests run?
背景: 所以,我试图做一个测试,看看使用 jQuery 绑定 "click" 事件的三种方法的性能差异s on.()
。我看到了一些相当大的差异(比我预期的要大得多),当 运行 一位同事的结果时,他注意到,如果你改变测试运行的顺序,结果会改变,但同样 "out of whack".
所以,我决定做一个非常简单的测试:
1) 一个 parent <div>
包含 100 child <div>
s,每个里面只有一个数字 (1-100) 和 class
值 "target-element".
2) 每个元素都有一个绑定到它的 click
事件,使用这个:
$(".target-element", "#context1").on("click", logClick);
3) click
事件只是将文本值设置为局部变量:
function logClick() {
var sTextVal = $(this).text();
}
4) 然后,我设置了一个 "trigger" 函数来调用对所有 child <div>
s:
的点击
function triggerClicks(context) {
$(context).find(".target-element").each(function() {
$(this).click();
});
});
5) 然后,我设置了 3 个测试运行,它们都调用 EXACT 相同的测试:
运行 1 ---> triggerClicks("#context1");
运行 2 ---> triggerClicks("#context1");
运行 3 ---> triggerClicks("#context1");
你可以在这里看到测试:http://jsperf.com/jsperf-perf-test
我测试的所有浏览器的结果都大不相同,随着运行的继续,结果越来越慢:
Chrome 41
Run 1 ---> 59.91 Ops/sec (±6.55%) - fastest
Run 2 ---> 32.72 Ops/sec (±5.06%) - 45% slower
Run 3 ---> 23.69 Ops/sec (±3.39%) - 59% slower
火狐 36
Run 1 ---> 52.69 Ops/sec (±10.21%) - fastest
Run 2 ---> 26.70 Ops/sec (±6.38%) - 48% slower
Run 3 ---> 15.95 Ops/sec (±24.55%) - 73% slower
IE 9
Run 1 ---> 26.98 Ops/sec (±14.43%) - fastest
Run 2 ---> 11.77 Ops/sec (±8.89%) - 54% slower
Run 3 ---> 7.54 Ops/sec (±6.85%) - 70% slower
那么我在这里缺少什么?我意识到这是一个重复性测试,并且要处理很多元素,但这不应该对运行结果产生太大影响。谁能看出我的代码会导致这种情况发生的任何原因,而不是 JSPerf 的严重错误?
如果您查看表单中准备代码字段旁边的帮助文本:
runs before each clocked test loop, outside of the timed code region
这意味着代码是 运行 在每个测试用例之前,而不是只有一次。因此,在第二个测试用例中,每个元素都有两个事件处理程序,第三个测试用例中有三个。
这就是为什么在准备字段正下方有一个 "teardown" 字段的原因:它应该用于撤消您在设置中所做的操作,以避免出现此类情况。如果将此添加到拆解中:
$(".target-element", "#context1").off("click");
然后在添加新事件处理程序之前删除现有的事件处理程序,并且测试花费与 运行 大致相同的时间。
背景: 所以,我试图做一个测试,看看使用 jQuery 绑定 "click" 事件的三种方法的性能差异s on.()
。我看到了一些相当大的差异(比我预期的要大得多),当 运行 一位同事的结果时,他注意到,如果你改变测试运行的顺序,结果会改变,但同样 "out of whack".
所以,我决定做一个非常简单的测试:
1) 一个 parent <div>
包含 100 child <div>
s,每个里面只有一个数字 (1-100) 和 class
值 "target-element".
2) 每个元素都有一个绑定到它的 click
事件,使用这个:
$(".target-element", "#context1").on("click", logClick);
3) click
事件只是将文本值设置为局部变量:
function logClick() {
var sTextVal = $(this).text();
}
4) 然后,我设置了一个 "trigger" 函数来调用对所有 child <div>
s:
function triggerClicks(context) {
$(context).find(".target-element").each(function() {
$(this).click();
});
});
5) 然后,我设置了 3 个测试运行,它们都调用 EXACT 相同的测试:
运行 1 ---> triggerClicks("#context1");
运行 2 ---> triggerClicks("#context1");
运行 3 ---> triggerClicks("#context1");
你可以在这里看到测试:http://jsperf.com/jsperf-perf-test
我测试的所有浏览器的结果都大不相同,随着运行的继续,结果越来越慢:
Chrome 41
Run 1 ---> 59.91 Ops/sec (±6.55%) - fastest
Run 2 ---> 32.72 Ops/sec (±5.06%) - 45% slower
Run 3 ---> 23.69 Ops/sec (±3.39%) - 59% slower
火狐 36
Run 1 ---> 52.69 Ops/sec (±10.21%) - fastest
Run 2 ---> 26.70 Ops/sec (±6.38%) - 48% slower
Run 3 ---> 15.95 Ops/sec (±24.55%) - 73% slower
IE 9
Run 1 ---> 26.98 Ops/sec (±14.43%) - fastest
Run 2 ---> 11.77 Ops/sec (±8.89%) - 54% slower
Run 3 ---> 7.54 Ops/sec (±6.85%) - 70% slower
那么我在这里缺少什么?我意识到这是一个重复性测试,并且要处理很多元素,但这不应该对运行结果产生太大影响。谁能看出我的代码会导致这种情况发生的任何原因,而不是 JSPerf 的严重错误?
如果您查看表单中准备代码字段旁边的帮助文本:
runs before each clocked test loop, outside of the timed code region
这意味着代码是 运行 在每个测试用例之前,而不是只有一次。因此,在第二个测试用例中,每个元素都有两个事件处理程序,第三个测试用例中有三个。
这就是为什么在准备字段正下方有一个 "teardown" 字段的原因:它应该用于撤消您在设置中所做的操作,以避免出现此类情况。如果将此添加到拆解中:
$(".target-element", "#context1").off("click");
然后在添加新事件处理程序之前删除现有的事件处理程序,并且测试花费与 运行 大致相同的时间。