'keys.each'和'each_key'有什么区别?

时间:2017-10-02 19:31:18

标签: ruby performance

当迭代如下所示的哈希时:

hash.keys.each do |key|
  process_key(key)
end

Rubocop宣称我应该使用:

each_key

而不是:

keys.each

keys.eacheach_key之间的“关键”区别是什么?

2 个答案:

答案 0 :(得分:4)

由于性能原因,Rubocop希望您根据评估的代码执行此操作。使用大量数据就会变得明显。这是关于它的文档:https://github.com/bbatsov/rubocop/blob/master/manual/cops_performance.md#performancehasheachmethods

我还找到了有人编写的基准来测试这个:https://gist.github.com/jodosha/8ca2bee6137be94e9dcb

我修改了一下并在我的系统上运行它:

Warming up --------------------------------------
         string each   128.742k i/100ms
         string keys   114.523k i/100ms
     string each_key   134.279k i/100ms
         symbol each   128.838k i/100ms
         symbol keys   109.398k i/100ms
     symbol each_key   132.021k i/100ms
Calculating -------------------------------------
         string each      2.053M (± 4.0%) i/s -     10.299M in   5.026890s
         string keys      1.864M (± 1.4%) i/s -      9.391M in   5.039759s
     string each_key      2.224M (± 5.5%) i/s -     11.145M in   5.032201s
         symbol each      2.082M (± 1.0%) i/s -     10.436M in   5.013145s
         symbol keys      1.815M (± 2.1%) i/s -      9.080M in   5.004690s
     symbol each_key      2.240M (± 1.9%) i/s -     11.222M in   5.012184s

Comparison:
     symbol each_key:  2239720.0 i/s
     string each_key:  2224205.1 i/s - same-ish: difference falls within error
         symbol each:  2081895.2 i/s - 1.08x  slower
         string each:  2052884.9 i/s - 1.09x  slower
         string keys:  1863740.5 i/s - 1.20x  slower
         symbol keys:  1815131.1 i/s - 1.23x  slower

链接方法比使用内置方法(在本例中)使用单个特殊枚举器完成任务要慢。语言创造者把它放在那里是有原因的,也是它的惯用语。

答案 1 :(得分:2)

Rubocop错了。您应该使用哪一个取决于您想要的返回值。

  1. 如果您想要返回一系列密钥,则应使用keys.eachkey创建一个新的键数组,each在每个键上执行块后返回该键数组。
  2. 如果你不需要一个键数组(并且想要原来的哈希值),那么你应该使用each_key,因为这不会创建一个不会被使用的数组,并且会更高效