此代码的执行时间约为1秒:
start_time = Time.now
prev = 1
(1..1000).each do |i|
(1..10000).each do |j|
result = j * prev
result = result + prev
result = result - prev
result = result / prev
prev = j
end
end
end_time = Time.now
printf('%f sec', end_time - start_time)
但是当我使用一个10000000次迭代的循环(而不是上面写的2个循环,1000次和10000次迭代)时,它会慢得多(大约4.5秒):
start_time = Time.now
prev = 1
(1..10000000).each do |j|
result = j * prev
result = result + prev
result = result - prev
result = result / prev
prev = j
end
end_time = Time.now
printf('%f sec', end_time - start_time)
为什么会这样?总迭代次数仍然相同。
答案 0 :(得分:2)
第二个示例处理的数字比第一个示例大得多(如上面评论的@Sergii K)。第二个示例代码可能达到系统上的最大Fixnum限制。在32位系统上,maximum signed integer为j * prev
,远小于第二个示例中的最大乘积(2**(0.size * 8 -2) -1).class # => Fixnum vs:
(2**(0.size * 8 -2) -1 + 1).class # => should be Bignum
(与第一个示例中的最大乘积相反)。在这种情况下,ruby必须在内部将Fixnums转换为Bignums,这就是为什么第二个示例代码可能比第一个示例代码慢。
在64位系统上,我希望两个样本大致同时运行,因为最大的整数永远不会达到Fixnum限制。这就是为什么大多数其他评论者可能没有看到时间上的巨大差异。
更新:如果最大Fixnum数字仅为1073741823,如上面的OP所评论,那么它必须意味着虽然操作系统本身是64位,也许安装的ruby也是64 -bit ruby,它仍然只使用4个字节来存储Fixnum数字(而不是真正的64位红宝石中的8个)。在第二个例子中,最大整数值要小得多,所以它确实必须将较高的数字转换为Bignums,这是第二个样本的缓慢来源。
如果你比较,你可以自己检查一下:
function sortArr($a, $b) {
return intval(preg_replace('/[^0-9]+/', '', $a['id']), 10) - intval(preg_replace('/[^0-9]+/', '', $b['id']), 10) ; // it will extract number from string and compare it
}
usort($avaliableArray, 'sortArr');