如果执行频率更高,相同的代码需要更长的时间
Same code takes longer if executed more often?
我在一个网页上的<script>
标签中有以下代码,上面没有其他内容。恐怕我目前还没有在线代码。正如你所看到的,它以两种不同的方式将200万以下的所有素数相加,并计算出平均耗时。变量howOften
用于多次执行此操作,因此您可以对其进行平均。让我困惑的是,对于howOften == 1
,方法2更快,但对于howOften == 10
,方法1更快。这种差异是显著的,即使你打了几次F5也会保持不变。
我的问题很简单:怎么会这样?
(这篇文章经过了编辑,采纳了alf的建议。但这并没有什么区别!我现在非常困惑。)
(再次编辑:howOften
达到或超过1000,时间似乎稳定。Alf的答案似乎是正确的。)
function methodOne(maxN) {
var sum, primes_inv, i, j;
sum = 0;
primes_inv = [];
for ( var i = 2; i < maxN; ++i ) {
if ( primes_inv[i] == undefined ) {
sum += i;
for ( var j = i; j < maxN; j += i ) {
primes_inv[j] = true;
}
}
}
return sum;
}
function methodTwo(maxN) {
var i, j, p, sum, ps, n;
n = ((maxN - 2) / 2);
sum = n * (n + 2);
ps = [];
for(i = 1; i <= n; i++) {
for(j = i; j <= n; j++) {
p = i + j + 2 * i * j;
if(p <= n) {
if(ps[p] == undefined) {
sum -= p * 2 + 1;
ps[p] = true;
}
}
else {
break;
}
}
}
return sum + 2;
}
// ---------- parameters
var howOften = 10;
var maxN = 10000;
console.log('iterations: ', howOften);
console.log('maxN: ', maxN);
// ---------- dry runs for warm-up
for( i = 0; i < 1000; i++ ) {
sum = methodOne(maxN);
sum = methodTwo(maxN);
}
// ---------- method one
var start = (new Date).getTime();
for( i = 0; i < howOften; i++ )
sum = methodOne(maxN);
var stop = (new Date).getTime();
console.log('methodOne: ', (stop - start) / howOften);
// ---------- method two
for( i = 0; i < howOften; i++ )
sum = methodTwo(maxN);
var stop2 = (new Date).getTime();
console.log('methodTwo: ', (stop2 - stop) / howOften);
JS运行时是一个优化的JIT编译器。这意味着,在一段时间内,您的代码会被解释(tint),之后,它会被编译(tjitun)。
现在,您计算的很可能是(tint+tjitunun,不幸的是,这种比较没有多大意义。
所以答案是,我不知道。为了得到正确的答案,
- 将要评测的代码提取到函数中
- 对这些功能运行预热循环,不要使用预热循环中的计时
- 无论是热身还是测量,都要跑1….10次以上
- 尝试将测量时间的顺序替换为算法
- 如果可以的话,进入JS解释器的内部,并确保你了解发生了什么:你真的衡量你认为你做了什么吗?JIT是否在预热周期中运行,而不是在测量时运行?等等
更新:还要注意,在1个周期内,您得到的运行时间小于系统计时器的分辨率,这意味着错误可能大于您比较的实际值。
methodTwo只需要处理器执行更少的计算。在methodOne中,您的初始for循环最多执行N次。在methodTwo中,您的初始for循环执行(maxN-2)/2次。因此,在第二种方法中,处理器所做的计算数量不到第一种方法的一半。每个方法都包含一个嵌套的for循环,这一事实加剧了这种情况。所以方法一的big-O是maxN^2。而方法二的big-O是((maxN-2)/2)^2。
相关文章:
- 正在从帧创建时间代码
- Jquery时间启动计时器,我有一个计时器的代码,但它在页面加载时启动
- 如何检索AMD的XHR响应代码(+时间戳)'大型Dojo
- 为什么这个代码不起作用?我花了很长时间试图弄清楚这一点
- 如何使用java脚本代码计算禁用按钮的时间
- 来自服务器和本地时间的PHP或Javascript日期和时间代码
- JavaScript代码执行时间
- JavaScript:相同的代码需要不同的时间来执行
- 在页面首次加载时执行 jQuery 代码,然后在一段时间后加载
- 在一段时间后持续运行 JavaScript 代码
- php 代码以获取时区和当前系统时间与 GMT 的差异
- 根据日期/时间有条件地运行代码
- 在页面加载后淡出对象一段时间,然后在淡出后运行另一组代码
- 运行代码一段时间
- JavaScript:通过单击按钮来捕获系统时间的代码
- 如何从此代码中删除时间
- 我想在代码点火器的datetimepicker中禁用过去的时间
- 设置Javascript时间&来自SQL数据库和asp.net代码隐藏页的时区
- TileMill/MapBox的时间线代码
- 代码在Javascript中运行的时间/频率