gpt4 book ai didi

Ruby each vs while 循环性能

转载 作者:数据小太阳 更新时间:2023-10-29 06:44:26 25 4
gpt4 key购买 nike

试图解决Ruby中的一个基本算法问题,并测试性能。

为了以防万一,该算法旨在找到可被 1 到 20 之间的所有数字整除的最小正数。这是代码:

def remainder(number) # with while
divisor = 2
while divisor < 21
return false unless number % divisor == 0
divisor += 1
end
true
end

def remainder(number) # with each
(2..20).each do |divisor|
return false unless number % divisor == 0
end
true
end

number = 180_000_000
while number < 10_000_000_000
if remainder number
puts "#{number}"
break
end
number += 1
end

在我的电脑上,对于 while 版本,Ruby 大约需要 10 秒,对于每个版本,解析需要 70 到 80 秒。代码做完全相同的事情,给出相同的结果。为什么会有如此大的性能差异?

最佳答案

似乎成本是通过以下方式添加的:

  1. 为范围对象 (2..20) 创建枚举器
  2. each 中调用 block

这是一个基准

require 'benchmark'

c = 100_000
Benchmark.bm(7) do |x|
x.report("range - 1 :") { c.times { (2..20) } }
x.report("range - 2 :") { c.times { (2..20).each } }
x.report("range - 3 :") { c.times { (2..20).each { |x| x } } }
end

上面的示例输出是:

              user     system      total        real
range - 1 : 0.000000 0.000000 0.000000 ( 0.006004)
range - 2 : 0.031000 0.000000 0.031000 ( 0.026017)
range - 3 : 0.125000 0.000000 0.125000 ( 0.122081)
[Finished in 0.4s]

可以看出,创建 Range 对象不是问题,但是为它创建一个枚举器会增加时间,并将一个 block 传递给该迭代器并执行一些代码,会进一步增加成本。

与此相比,while 循环实现执行的是原始操作。因此,更快。

请注意,for 循环的性能与 each 一样糟糕,因为它或多或少等同于 each 实现

关于Ruby each vs while 循环性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32628360/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com