Ruby range 展开为何比 while 慢很多

lilijreey · October 16, 2018 · Last by a-wing replied at October 17, 2018 · 1579 hits
def rran()
  s = 0
  (0..10000000).each do |i|
    s += i
  end
end

def tfor()
  n=0
  s=0
  while (n+=1) < 10000000
    s+=n
  end

end
[148] pry(main)> Benchmark.measure { tfor()}
=> #<Benchmark::Tms:0x000000029cf458
 @cstime=0.0,
 @cutime=0.0,
 @label="",
 @real=0.22141856199596077,
 @stime=0.0,
 @total=0.21999999999999997,
 @utime=0.21999999999999997>
[149] pry(main)> Benchmark.measure { rran()}                                                              
=> #<Benchmark::Tms:0x00000002969388
 @cstime=0.0,
 @cutime=0.0,
 @label="",
 @real=0.3831686199409887,
 @stime=0.0,
 @total=0.3700000000000001,
 @utime=0.3700000000000001>

如图 for 版本的循环比 range 版本的快很多。按道理应该是一样快才对啊。请大牛解释一下

应该是 each 需要调用 block 的消耗吧,建议用更牛逼的 profile 工具试试能不能看?

如果这样 ruby 的优化还是很差劲的。

《Ruby 原理剖析》里面介绍过,each 方法每次迭代都准备一大波对象,执行很多逻辑。而 while 只需要调整 PC 指针的值,性能不在一个量级。具体的细节我得回去翻翻书了。

Reply to early

好吧,那这样有回到 while/ for 的老路了。感觉 echo 调用 block 可以内联编译。难道 ruby 的解释器没有优化功能吗。

你去读完 Ruby原理剖析 再回来问问题吧(((

Reply to lilijreey

each 方法 其实和其他方法的实现不一样。。。。印象中 each 应该更快。((

我只是猜测。while 执行更快可能仅限于一些简单数值

while/ for 在遍历比较大的对象好像有其他问题(

You need to Sign in before reply, if you don't have an account, please Sign up first.