加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在某些情况下,为什么Ruby的Hash#值比Hash#each_value更快?

发布时间:2020-12-17 02:08:57 所属栏目:百科 来源:网络整理
导读:当我将each_value应用于散列时,它比使用值时要长得多,即使each_value表面上避免分配和复制数组. 我写了一个简单的比较: require 'benchmark/ips'some_hash = File.open('with_an.dat') { |f| Marshal.load f }Benchmark.ips do |x| x.report "calling each_
当我将each_value应用于散列时,它比使用值时要长得多,即使each_value表面上避免分配和复制数组.

我写了一个简单的比较:

require 'benchmark/ips'

some_hash = File.open('with_an.dat') { |f| Marshal.load f }

Benchmark.ips do |x|
  x.report "calling each_value" do
    some_hash.each_value
  end
  x.report "calling values" do
    some_hash.values
  end
  x.compare!
end

Benchmark.ips do |x|
  x.report "summing each_value" do
    some_hash.each_value.inject &:+
  end
  x.report "summing values" do
    some_hash.values.inject &:+
  end
  x.compare!
end

以下是结果:

Calculating -------------------------------------
  calling each_value    58.166k i/100ms
      calling values     2.000  i/100ms
-------------------------------------------------
  calling each_value      1.312M (±40.7%) i/s -      5.468M
      calling values     29.423  (±10.2%) i/s -    146.000 

Comparison:
  calling each_value:  1312156.6 i/s
      calling values:       29.4 i/s - 44596.28x slower

Calculating -------------------------------------
  summing each_value     1.000  i/100ms
      summing values     1.000  i/100ms
-------------------------------------------------
  summing each_value      2.107  (± 0.0%) i/s -     11.000 
      summing values      8.002  (±12.5%) i/s -     40.000 

Comparison:
      summing values:        8.0 i/s
  summing each_value:        2.1 i/s - 3.80x slower

正如所料,只是调用每个方法,each_value要快得多,因为它只需要创建一个Enumerator,并且实际上不会遍历哈希表.同时,值必须复制整个数组.

然而,当我添加值时,似乎each_value方法比值方法慢3倍.那为什么会这样?

解决方法

迭代哈希比迭代数组更慢:

? Benchmark.bm do |x|
 ?   x.report do
 ?     n.times do
 ?       {a: 1,b: 2,c: 3,d: 4,e: 5}.inject(1) { |memo,(_,v)| memo * v }
 ?     end
 ?   end
 ?   x.report do
 ?     n.times do
 ?       [1,2,3,4,5].inject(1) { |memo,v| memo * v }
 ?     end
 ?   end
 ? end

 #?      user     system      total        real
 #?  0.700000   0.010000   0.710000 (  0.712821)
 #?  0.340000   0.000000   0.340000 (  0.349040)

通过调用each_value实际上迭代原始Hash实例,同时通过调用values.each迭代正在Array实例上完成(值.)

要回答“为什么会这样”的问题,我们应该看看不同ruby版本的rb_hash_foreach和rb_array_foreach本机实现.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读