【发布时间】:2015-02-12 11:33:47
【问题描述】:
警告:这没什么实用价值。我只是想知道发生了什么事。
我在网上多次遇到过这条线:
return to_enum __method__ unless block_given?
我想测试它并用它创建一个生成器方法(#1),然后我尝试不使用它并想出了一个枚举器(#2)。我对此很满意,认为应该这样做 - 尽管后来我想出了一个使用 #lazy (#3) 的解决方案,我认为它看起来更优雅。
你能猜出哪个最快吗?令我惊讶的是,#1 是最快的,其次是 #2 和 #3!
对我来说,第一个看起来有点像 hack,并且如果你给它一个空块(而不是在给出一个块时抛出一个错误),它会有一些不良行为,例如停止。
我的问题是,最快的方法是什么? 为什么 #1 比 #2 快,我错过了什么?如果我的解决方案没问题,客观上哪个是最好的?
编辑:更简单的例子,之前是 fizzbuzz (http://pastebin.com/kXbbfxBc)
def method
return to_enum __method__ unless block_given?
n = 0
loop do
n += 1
yield n ** 2
end
end
enum = Enumerator.new do |yielder|
n = 0
loop do
n += 1
yielder.yield n ** 2
end
end
lazy = (1..Float::INFINITY).lazy.map do |n|
n ** 2
end
p method.take 50
p enum.take 50
p lazy.first 50
require 'benchmark/ips'
Benchmark.ips do |bm|
bm.report('Method'){ method.take 50 }
bm.report('Enumerator'){ enum.take 50 }
bm.report('Lazy'){ lazy.first 50 }
bm.compare!
end
【问题讨论】:
-
请将您的问题放在问题中,而不是在某个随机网站上发布最重要的部分。
-
@JörgWMittag 粘贴箱?几乎不是一个随机的网站,它有 68 行 - 确实太多了,无法提出问题。如果你指的是标题,我在措辞上很吃力,我不介意你编辑它。
-
@user21033168 也许你可以想出一个更短的例子。我认为您的问题与 fizz-buzz 算法无关,是吗?
-
@Stefan 好的,谢谢。
标签: ruby performance enumerator lazy-sequences