这是这个答案的后续,关于 ruby 1.8.7 的 Symbol#to_proc 每次调用都会生成一个新的 proc。
似乎发生的事情比答案所暗示的要多。
这是一些示例代码:
def ctob
h=Hash.new(0)
ObjectSpace.each_object(Object) {|e| h[e.class]+=1 }
h
end
r=(0...1000)
p ctob
r.map(&:to_i)
p ctob
这表明正在创建大约一千个数组。这表明大约有一千个是空的:
c=0; ObjectSpace.each_object(Array){|e| c+=1 if e.empty? }
另一个有趣的事情是只有一个 Proc 对象存在。这表明to_proc
只调用一次。map
(如果我第二次用符号调用,也许会创建另一个。)
如果我将 map 调用更改为使用块,则不会创建这些数组。这也可以解释为什么 Andrew Grimm 的缓存对基准测试没有帮助。为什么要创建这些数组?
更新
显然,从 Symbol 创建的 proc 每次调用时都会创建一个空数组。
如果我将map
上面的行替换为
pr=:to_i.to_proc; r.map(&pr)
导致创建数组,但这
pr=proc{|e|e.to_i}; r.map(&pr)
才不是。如果我只做 pr.call(value),也会发生类似的事情。
(什么时候proc不是proc?)