Ruby 的 `lazy` 性能不如分配巨大的列表?
Ruby's `lazy` less performant than allocating huge lists?
我正在尝试处理大量数字:
require 'benchmark'
N = 999999
Benchmark.bm 10 do |bm|
bm.report 'Eager:' do
(0..N).select(&:even?).map{|x| x * x}.reduce(&:+)
end
bm.report 'Lazy:' do
(0..N).lazy.select(&:even?).map{|x| x * x}.reduce(&:+)
end
end;
根据我的理解,惰性版本应该快得多,因为急切版本需要分配两个列表,每个列表有 50 万个项目(一个用于 select
,一个用于 map
),而懒惰的版本正在流式传输所有内容。
然而,当我运行它的时候,懒惰的版本比急切的要多一倍多! (http://rextester.com/OTEX7399)
user system total real
Eager: 0.210000 0.010000 0.220000 ( 0.216572)
Lazy: 0.580000 0.000000 0.580000 ( 0.635091)
怎么可能?
我会说枚举器是一个比内存慢得多的中间人。
这也是 reported a while back and Ruby core team member Yusuke Endoh said:
Enumerator::Lazy is not a silver bullet; it removes the overhead for
creating an intermediate array, but brings the drawback for calling
a block. Unfortunately, the latter is much bigger than the former.
Thus, in general, Lazy does bring performance drawback.
我刚刚想到的一个类比:假设您正在为朋友制作家具。
非懒惰:你建造了整个东西,租了一辆卡车,然后开给你的朋友。
懒惰:你造了个小东西,开着车开给你的朋友。你建造下一个小部件,然后用你的车把它开给你的朋友。你建造下一个小部件,然后用你的车把它开给你的朋友。依此类推
是的,租那辆卡车是额外的开销,但与你的车一遍又一遍地驾驶相比,这算不了什么。
懒惰可以节省时间的真正原因是,在前几件作品之后,你的朋友发现你和他的妻子睡过,所以现在你们不再是朋友,他不再想要你的愚蠢家具了,你根本没有在构建剩余的部分。
我正在尝试处理大量数字:
require 'benchmark'
N = 999999
Benchmark.bm 10 do |bm|
bm.report 'Eager:' do
(0..N).select(&:even?).map{|x| x * x}.reduce(&:+)
end
bm.report 'Lazy:' do
(0..N).lazy.select(&:even?).map{|x| x * x}.reduce(&:+)
end
end;
根据我的理解,惰性版本应该快得多,因为急切版本需要分配两个列表,每个列表有 50 万个项目(一个用于 select
,一个用于 map
),而懒惰的版本正在流式传输所有内容。
然而,当我运行它的时候,懒惰的版本比急切的要多一倍多! (http://rextester.com/OTEX7399)
user system total real
Eager: 0.210000 0.010000 0.220000 ( 0.216572)
Lazy: 0.580000 0.000000 0.580000 ( 0.635091)
怎么可能?
我会说枚举器是一个比内存慢得多的中间人。
这也是 reported a while back and Ruby core team member Yusuke Endoh said:
Enumerator::Lazy is not a silver bullet; it removes the overhead for creating an intermediate array, but brings the drawback for calling a block. Unfortunately, the latter is much bigger than the former. Thus, in general, Lazy does bring performance drawback.
我刚刚想到的一个类比:假设您正在为朋友制作家具。
非懒惰:你建造了整个东西,租了一辆卡车,然后开给你的朋友。
懒惰:你造了个小东西,开着车开给你的朋友。你建造下一个小部件,然后用你的车把它开给你的朋友。你建造下一个小部件,然后用你的车把它开给你的朋友。依此类推
是的,租那辆卡车是额外的开销,但与你的车一遍又一遍地驾驶相比,这算不了什么。
懒惰可以节省时间的真正原因是,在前几件作品之后,你的朋友发现你和他的妻子睡过,所以现在你们不再是朋友,他不再想要你的愚蠢家具了,你根本没有在构建剩余的部分。