Источник нерегулярита Ruby. - PullRequest
3 голосов
/ 02 декабря 2011

Выполнение этого кода:

require 'benchmark'

Benchmark.bm do |x|
  x.report("1+1") {15_000_000.times {1+1}}
  x.report("1+1") {15_000_000.times {1+1}}
  x.report("1+1") {15_000_000.times {1+1}}
  x.report("1+1") {15_000_000.times {1+1}}
  x.report("1+1") {15_000_000.times {1+1}}
end

Вывод этих результатов:

       user     system      total        real
1+1  2.188000   0.000000   2.188000 (  2.250000)
1+1  2.250000   0.000000   2.250000 (  2.265625)
1+1  2.234000   0.000000   2.234000 (  2.250000)
1+1  2.203000   0.000000   2.203000 (  2.250000)
1+1  2.266000   0.000000   2.266000 (  2.281250)

Предположение о том, что результат является результатом системной среды, но хотел подтвердить, что это так.

Ответы [ 2 ]

2 голосов
/ 02 декабря 2011

«Угадай, что вариация является результатом системной среды», вы правы.

Тесты не могут быть точными все время.У вас нет идеальной обычной машины, чтобы запускать что-то всегда в одно и то же время.Возьмите два числа из эталона, как те же, если они были слишком близко, как в этом случае.

0 голосов
/ 05 декабря 2011

Я попытался использовать eval, чтобы частично развернуть цикл, и, хотя это сделало его быстрее, это сделало время выполнения менее согласованным!

$VERBOSE &&= false # You do not want 15 thousand "warning: useless use of + in void context" warnings
# large_number = 15_000_000 # Too large! Caused eval to take too long, so I gave up
somewhat_large_number = 15_000
unrolled = "def do_addition\n" + ("1+1\n" * somewhat_large_number) + "end\n" ; nil
eval(unrolled)

require 'benchmark'

Benchmark.bm do |x|
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
  x.report("1+1 partially unrolled") { i = 0; while i < 1000; do_addition; i += 1; end}
end

дал мне

      user     system      total        real
1+1 partially unrolled  0.750000   0.000000   0.750000 (  0.765586)
1+1 partially unrolled  0.765000   0.000000   0.765000 (  0.765586)
1+1 partially unrolled  0.688000   0.000000   0.688000 (  0.703089)
1+1 partially unrolled  0.797000   0.000000   0.797000 (  0.796834)
1+1 partially unrolled  0.750000   0.000000   0.750000 (  0.749962)
1+1 partially unrolled  0.781000   0.000000   0.781000 (  0.781210)
1+1 partially unrolled  0.719000   0.000000   0.719000 (  0.718713)
1+1 partially unrolled  0.750000   0.000000   0.750000 (  0.749962)
1+1 partially unrolled  0.765000   0.000000   0.765000 (  0.765585)
1+1 partially unrolled  0.781000   0.000000   0.781000 (  0.781210)

Для сравнения ваш эталонный тест на моем компьютере дал

      user     system      total        real
1+1  2.406000   0.000000   2.406000 (  2.406497)
1+1  2.407000   0.000000   2.407000 (  2.484629)
1+1  2.500000   0.000000   2.500000 (  2.734655)
1+1  2.515000   0.000000   2.515000 (  2.765908)
1+1  2.703000   0.000000   2.703000 (  4.391075)

(реальное время изменялось в последней строке, но не пользовательское или общее)

...