Интуитивно, последний должен быть быстрее первого. Тем не менее, я был очень удивлен, когда увидел результаты тестов:
require 'benchmark/ips'
b = (0..20).to_a;
y = 21;
Benchmark.ips do |x|
x.report('<<') { a = b.dup; a << y }
x.report('+=') { a = b.dup; a += [y] }
x.report('push') { a = b.dup; a.push(y) }
x.report('[]=') { a = b.dup; a[a.size]=y }
x.compare!
end
Результат:
Calculating -------------------------------------
<< 24.978k i/100ms
+= 30.389k i/100ms
push 24.858k i/100ms
[]= 22.306k i/100ms
-------------------------------------------------
<< 493.125k (± 3.2%) i/s - 2.473M
+= 599.830k (± 2.3%) i/s - 3.009M
push 476.374k (± 3.3%) i/s - 2.386M
[]= 470.263k (± 3.8%) i/s - 2.364M
Comparison:
+=: 599830.3 i/s
<<: 493125.2 i/s - 1.22x slower
push: 476374.0 i/s - 1.26x slower
[]=: 470262.8 i/s - 1.28x slower
Однако, когда мой коллега самостоятельно создал свой собственный тест, результат был совершенно противоположным:
Benchmark.ips do |x|
x.report('push') {@a = (0..20).to_a; @a.push(21)}
x.report('<<') {@b = (0..20).to_a; @b << 21}
x.report('+=') {@c = (0..20).to_a; @c += [21]}
x.compare!
end
Результат:
Calculating -------------------------------------
push 17.623k i/100ms
<< 18.926k i/100ms
+= 16.079k i/100ms
-------------------------------------------------
push 281.476k (± 4.2%) i/s - 1.410M
<< 288.341k (± 3.6%) i/s - 1.457M
+= 219.774k (± 8.3%) i/s - 1.093M
Comparison:
<<: 288341.4 i/s
push: 281476.3 i/s - 1.02x slower
+=: 219774.1 i/s - 1.31x slower
Мы также перекрещивали наши тесты, и на обеих наших машинах его бенчмарк показал, что +=
заметно медленнее, чем <<
, а мой показал противоположное.
Почему это?
UPD: моя Ruby версия Ruby 2.2.3p173 (2015-08-18 версия 51636) [x86_64-darwin14]; мой коллега - 2.2.2 (Не знаю полной информации, завтра будет обновлять сообщение).
UPD2: ruby 2.2.2p95 (версия 2015-04-13 версия 50295) [x86_64-darwin12.0] моя версия для румынов с русским партнером.