The default value (predicate) of the Style/NumericPredicate cop, produces slower code.
My opinion is that rubocop should default to the faster method, with the option of having the other layout.
Tested with Benchmark-ips & ruby 2.0, 2.1, 2.2, 2.3, 2.4dev
RuboCop::Cop::Style::NumericPredicate
Benchmark
Warming up --------------------------------------
== 0 94.390k i/100ms
zero? 80.343k i/100ms
Calculating -------------------------------------
== 0 2.498M (卤 4.7%) i/s - 12.459M in 5.002912s
zero? 1.804M (卤 8.5%) i/s - 8.918M in 5.010642s
Comparison:
== 0: 2498260.4 i/s
zero?: 1803547.9 i/s - 1.39x slower
"== 0" is faster
Warming up --------------------------------------
!= 0 64.694k i/100ms
nonzero? 49.316k i/100ms
Calculating -------------------------------------
!= 0 1.949M (卤18.9%) i/s - 9.187M in 5.051024s
nonzero? 895.233k (卤26.2%) i/s - 4.093M in 5.066035s
Comparison:
!= 0: 1949177.3 i/s
nonzero?: 895233.2 i/s - 2.18x slower
!= 0" is faster
Warming up --------------------------------------
> 0 83.342k i/100ms
positive? 73.005k i/100ms
Calculating -------------------------------------
> 0 2.629M (卤 3.3%) i/s - 13.168M in 5.014540s
positive? 1.567M (卤 1.7%) i/s - 7.885M in 5.032639s
Comparison:
> 0: 2629417.0 i/s
positive?: 1567175.2 i/s - 1.68x slower
"> 0" is faster
Warming up --------------------------------------
< 0 91.912k i/100ms
negative? 82.470k i/100ms
Calculating -------------------------------------
< 0 2.328M (卤 1.2%) i/s - 11.673M in 5.015670s
negative? 1.952M (卤 0.5%) i/s - 9.814M in 5.027162s
Comparison:
< 0: 2327595.1 i/s
negative?: 1952235.9 i/s - 1.19x slower
"< 0" is faster
Test code example:
def self.slow_zero
0.zero?
1.zero?
-1.zero?
9558.zero?
-9558.zero?
1565156.zero?
-1565156.zero?
end
def self.fast_zero
0 == 0
1 == 0
-1 == 0
9558 == 0
-9558 == 0
1565156 == 0
-1565156 == 0
end
But is the performance difference significant? It looks like they are both very fast.
The result above has an average from about 62% slower.
But also the least result (1.19x slower) means that roughly i can do 5 times a < 0 and in the same time do 4 times a #negative?
I would have to disagree with this. This is a style cop, not a performance cop. Robustness and readability (in this case readability is about the same) should be the guiding force for the defaults, not speculative micro-optimizations based on the current Ruby implementation.
Language level optimizations are a nebulous thing, potentially leading to us having different defaults per Ruby version, because of changes to the internals. (We recently removed a performance cop because the performance difference had been nuked somewhere around MRI 2.2.)
If someone does millions of comparisons to zero and, after proper, in vivo benchmarks, find that this has become a bottleneck, they can configure the cop or disable it for this block.
I agree with @Drenmi.
One comment I still have: @Drenmi sad "Language level optimizations" -> It is slower on ruby 2.0, 2.1, 2.2, 2.3 and 2.4
https://travis-ci.org/dennisvandehoef/rubocop-speed/builds/167869584
Most helpful comment
I would have to disagree with this. This is a style cop, not a performance cop. Robustness and readability (in this case readability is about the same) should be the guiding force for the defaults, not speculative micro-optimizations based on the current Ruby implementation.
Language level optimizations are a nebulous thing, potentially leading to us having different defaults per Ruby version, because of changes to the internals. (We recently removed a performance cop because the performance difference had been nuked somewhere around MRI 2.2.)
If someone does millions of comparisons to zero and, after proper, in vivo benchmarks, find that this has become a bottleneck, they can configure the cop or disable it for this block.