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/