根据我之前的相关问题,我发现使用Enumerator
类生成无限序列时存在巨大的性能差距。在我确实相信问题在于Enumerable
方法之前take
,drop
但以下基准并未证实这一说法。
创建自然数生成器并以区间 (10e7-10, 10e7> 显示数字的示例:
require 'benchmark'
nats_range = (1..Float::INFINITY)
nats_enum = Enumerator.new {|y| i=1; loop { y << i; i+=1 }}
puts "#{'_'*79+"\n"}Benchmarking Enumerable methods on Range ..."
puts Benchmark.measure { print nats_range.take(10**7).drop(10**7-10), "\n" }
puts "#{'_'*79+"\n"}Benchmarking Enumerable methods on Enumerator ..."
puts Benchmark.measure { print nats_enum.take(10**7).drop(10**7-10), "\n" }
$ ruby a.rb
_______________________________________________________________________________
Benchmarking Enumerable methods on Range ...
[9999991, 9999992, 9999993, 9999994, 9999995, 9999996, 9999997, 9999998, 9999999, 10000000]
1.570000 0.010000 1.580000 ( 1.576761)
_______________________________________________________________________________
Benchmarking Enumerable methods on Enumerator ...
[9999991, 9999992, 9999993, 9999994, 9999995, 9999996, 9999997, 9999998, 9999999, 10000000]
15.620000 0.020000 15.640000 ( 15.665156)
使用 Enumerator 的等效代码要慢 10 倍!
我在这里问是否有人可以解释这种巨大的差异。我是否不正确地使用枚举器?这是当前 Ruby 实现中已知的回归吗?
核磁共振红宝石 1.9.3p385