ruby - 为什么 RuboCop 建议用 Array.new 替换 .times.map?

标签 ruby performance rubocop

RuboCop 建议:

Use Array.new with a block instead of .times.map.

docs对于警察:

This cop checks for .times.map calls. In most cases such calls can be replaced with an explicit array creation.

例子:

# bad
9.times.map do |i|
  i.to_s
end

# good
Array.new(9) do |i|
  i.to_s
end

我知道可以替换,但感觉9.times.map更接近英文语法,更容易理解代码的作用。

为什么要更换?

最佳答案

后者性能更高;这是一个解释:Pull request where this cop was added

It checks for calls like this:

9.times.map { |i| f(i) }
9.times.collect(&foo)

and suggests using this instead:

Array.new(9) { |i| f(i) }
Array.new(9, &foo)

The new code has approximately the same size, but uses fewer method calls, consumes less memory, works a tiny bit faster and in my opinion is more readable.

I've seen many occurrences of times.{map,collect} in different well-known projects: Rails, GitLab, Rubocop and several closed-source apps.

Benchmarks:

Benchmark.ips do |x|
  x.report('times.map') { 5.times.map{} }
  x.report('Array.new') { Array.new(5){} }
  x.compare!
end
__END__
Calculating -------------------------------------
           times.map    21.188k i/100ms
           Array.new    30.449k i/100ms
-------------------------------------------------
           times.map    311.613k (± 3.5%) i/s -      1.568M
           Array.new    590.374k (± 1.2%) i/s -      2.954M

Comparison:
           Array.new:   590373.6 i/s
           times.map:   311612.8 i/s - 1.89x slower

I'm not sure now that Lint is the correct namespace for the cop. Let me know if I should move it to Performance.

Also I didn't implement autocorrection because it can potentially break existing code, e.g. if someone has Fixnum#times method redefined to do something fancy. Applying autocorrection would break their code.

关于ruby - 为什么 RuboCop 建议用 Array.new 替换 .times.map?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41518896/

相关文章:

ruby-on-rails - Ruby on Rails - 发送联系表格 - Controller 问题

ruby - 如何忽略或跳过使用 RSpec 的测试方法?

C++ g++和msvc之间的不同文件读/写时间

python - Pandas 数据帧 : fastest way of updating multiple rows based on a list of dictionaries

xcode - React-Native 中的高 CPU 使用率

ruby-on-rails - 似乎无法使用 Rails 4 安装 rubocop gem

ruby-on-rails - byebug,接下来只进入应用程序代码

ruby-on-rails - 如何在 Ruby 中使用 X509Certificate 对 xml 进行签名?

ruby - VSCode/Rubocop 提示未配置的警察

ruby-on-rails - ruby-rubocop 无法加载此类文件 -- rubocop/rspec/focused