rubocop-performance
を確認していたら、
Performance/RangeInclude: Use Range#cover? instead of Range#include?.
が出たのでベンチマークを取ってみました。
require 'bundler/setup'
require 'benchmark_driver'
Benchmark.driver do |x|
x.prelude <<~RUBY
require 'active_support/time'
t = Time.current + 5.minutes
RUBY
x.report 'include?', %[ (Time.current..Float::INFINITY).include?(t) ]
x.report 'cover?', %[ (Time.current..Float::INFINITY).cover?(t) ]
x.report 'between?', %[ t.between?(Time.current, Float::INFINITY) ]
x.report 'raw_function', %[ t >= Time.current && t <= Float::INFINITY ]
end
結果
Warming up --------------------------------------
include? 85.071k i/s - 86.456k times in 1.016282s (11.75μs/i)
cover? 131.933k i/s - 135.600k times in 1.027793s (7.58μs/i)
between? 276.108k i/s - 285.615k times in 1.034434s (3.62μs/i)
raw_function 285.200k i/s - 291.396k times in 1.021725s (3.51μs/i)
Calculating -------------------------------------
include? 125.985k i/s - 255.212k times in 2.025732s (7.94μs/i)
cover? 133.774k i/s - 395.799k times in 2.958713s (7.48μs/i)
between? 304.505k i/s - 828.322k times in 2.720227s (3.28μs/i)
raw_function 304.348k i/s - 855.600k times in 2.811255s (3.29μs/i)
Comparison:
between?: 304504.7 i/s
raw_function: 304348.1 i/s - 1.00x slower
cover?: 133774.0 i/s - 2.28x slower
include?: 125985.1 i/s - 2.42x slower
include?
から cover?
に変更したほうが早いが、between?
や便利機能使わずに普通に書いた raw_function
の方が早くなりました。 後者の2つは実行するタイミングで順位がわかりましたが、ほぼ誤差の範囲だと思います。
ちなみに benchmark_driver
では、 ymlで入力することもサポートしているので、
# range.yml
prelude: |
require 'bundler/setup'
require 'active_support/time'
t = Time.current + 5.minutes
benchmark:
include?: (Time.current..Float::INFINITY).include?(t)
cover?: (Time.current..Float::INFINITY).cover?(t)
between?: t.between?(Time.current, Float::INFINITY)
raw_function: t >= Time.current && t <= Float::INFINITY
のようなファイルを用意して、
$ benchmark-driver range.yml
と書いても似たような結果を得られました。