Я сделал тест, согласно тому, что вы сказали:
require 'benchmark'
N = 1000
# the fast method
def p1(arr_param)
# lazy init of the arr_param, so it returns 20 times true and 80 times false
(arr_param << Array.new(20, true) << Array.new(80, false)).flatten! if arr_param.empty?
# shorter sleep
t = Time.now.to_f
while true
break if Time.now.to_f - t > 0.000_01
end
arr_param.shift
end
# the slow method
def p2
# longer sleep
t = Time.now.to_f
while true
break if Time.now.to_f - t > 0.001
end
true
end
# testing arrays
arr = (1..100).to_a
truth_arr = []
Benchmark.bm(7) do |b|
b.report('chain') { N.times { arr.select { |_| p1(truth_arr) }.select { |_| p2 } } }
b.report('and') { N.times { arr.select { |_| p1(truth_arr) && p2 } } }
end
Результаты:
#=> user system total real
#=> chain 78.422000 0.000000 78.422000 ( 78.789006)
#=> and 78.375000 0.000000 78.375000 ( 79.313160)
Так что, похоже, оба подхода одинаково быстры. Кто-то более знающий, чем я, должен был бы объяснить почему.