ruby中的#entries
模块的#to_a
和Enumerable
方法之间的基本区别是什么。似乎在Hash
上返回相同的结果
>> hash = {"name" => "foo" , "age" => "23"}
=> {"name"=>"foo", "age"=>"23"}
>> hash.to_a
=> [["name","foo"],["age",23]]
>> hash.entries
=> [["name","foo"],["age",23]]
答案 0 :(得分:15)
这是差异(查看# =>
之后的输出):
h = {}
h.method(:entries) # => #<Method: Hash(Enumerable)#entries>
h.method(:to_a) # => #<Method: Hash#to_a>
h.method(:entries).owner # => Enumerable
h.method(:to_a).owner # => Hash
Hash
有一个实例方法#to_a
,因此它不会调用Enumerable#to_a
。但是Hash
没有自己的方法#entries
,因此它正在调用Enumerable#entries
,因为Hash
包含Enumerable
模块。
Hash.included_modules # => [Enumerable, Kernel]
Enumerable#entries
和Enumerable#to_a
之间没有区别,据我所知,两者使用TracePoint的工作方式相似:
1. trace = TracePoint.new do |tp|
2. p [tp.lineno, tp.event, tp.defined_class,tp.method_id]
3. end
4.
5. trace.enable do
6. (1..2).entries
7. (1..2).to_a
8. end
# >> [5, :b_call, nil, nil]
# >> [6, :line, nil, nil]
# >> [6, :line, nil, nil]
# >> [6, :c_call, Enumerable, :entries]
# >> [6, :c_call, Range, :each]
# >> [6, :c_return, Range, :each]
# >> [6, :c_return, Enumerable, :entries]
# >> [7, :line, nil, nil]
# >> [7, :line, nil, nil]
# >> [7, :c_call, Enumerable, :to_a]
# >> [7, :c_call, Range, :each]
# >> [7, :c_return, Range, :each]
# >> [7, :c_return, Enumerable, :to_a]
# >> [8, :b_return, nil, nil]
是的,Hash#to_a
比Enumerable#to_a
快。
部分 - 我
require 'benchmark'
class Hash
remove_method :to_a
end
hsh = Hash[*1..1000]
Benchmark.bm(10) do |b|
b.report("Enumerable#to_a") { hsh.to_a }
end
# >> user system total real
# >> Enumerable#to_a 0.000000 0.000000 0.000000 ( 0.000126)
第二部分
require 'benchmark'
hsh = Hash[*1..1000]
Benchmark.bm(10) do |b|
b.report("Hash#to_a") { hsh.to_a }
end
# >> user system total real
# >> Hash#to_a 0.000000 0.000000 0.000000 ( 0.000095)