Как Rubinius и JRuby могут быть такими медленными?

Я решил посмотреть, сколько времени займет перебор массива хэшей. Ниже приведен код:

pairs = [{name: "firstname", value: "string"},{name: "lastname", value: "string"},{name: "country", value: "string"},{name: "city", value: "string"},{name: "state", value: "string"},{name: "company", value: "string"},{name: "year", value: "string"},{name: "political_affiliation", value: "string"},{name: "social_security_number", value: "string"}] * 1000
blank = {}

start = Time.now
pairs.each do |pair|
  blank[pair[:name]] = pair[:value]
end

p Time.now - start

Время вычисляется путем вычитания текущего времени после цикла из текущего времени до цикла.

Именно столько времени требовалось для вычислений в YARV 2.1.1, согласно математике в коде:

0.001962017

Вот сколько времени ушло на Rubinius 2.2.6:

0.022598

И jRuby 1.7.12

0.022317

Предположительно Rubinius и jRuby имеют преимущества в производительности по сравнению с YARV. Почему выполнение одной и той же базовой операции занимает почти в 12 раз больше времени? Это нормально или у меня что-то не так настроено?


person Ravenstine    schedule 04.06.2014    source источник
comment
Есть ли время, включая запуск среды?   -  person MxLDevs    schedule 05.06.2014
comment
Я не понимаю, как... если только я не понимаю, как среда для любого интерпретатора запустится после входа в код. Обратите внимание, как в коде время вычисляется путем вычитания Time.now перед циклом из текущего времени. Я предположил, что это будет достаточным способом проверить это.   -  person Ravenstine    schedule 05.06.2014
comment
Не могли бы вы повторить измерения с помощью benchmark/ips? Возможно, виртуальной машине Java/rbx просто нужно больше времени для прогрева…   -  person DMKE    schedule 05.06.2014


Ответы (1)


Вы проводите бенчмаркинг слишком маленькими временами, которые скомпрометированы загрузкой среды. По моему опыту, чтобы иметь надежные тесты, вы должны получить время не менее 10 секунд, чтобы уменьшить время прогрева. Примерно через 10 секунд я ожидаю, что JRuby будет наиболее производительным, за ним следуют Ruby и Rubinius.

Давайте посмотрим:

# so_24049371.rb

require 'benchmark'

# NOTE THIS: YOU SHOULD TWEAK IT IN ORDER TO HAVE BENCHMARKS OF ~ 10 SECONDS
MULTIPLIER = 5_000_000
pairs = [{name: "firstname", value: "string"},{name: "lastname", value: "string"},{name: "country", value: "string"},{name: "city", value: "string"},{name: "state", value: "string"},{name: "company", value: "string"},{name: "year", value: "string"},{name: "political_affiliation", value: "string"},{name: "social_security_number", value: "string"}] \
  * MULTIPLIER
blank = {}

puts Benchmark.measure {
  pairs.each do |pair|
    blank[pair[:name]] = pair[:value]
  end
}

# so_24049371.fish

source (rbenv init -|psub)

for ruby_version in 2.1.2 rbx-2.2.7 jruby-1.7.12
  rbenv shell $ruby_version
  ruby -v
  ruby so_24049371.rb
end

Это вывод на моей машине (я использую fish shell + rbenv, вы должны написать свой собственный скрипт):

> fish so_24049371.fish
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
  8.190000   0.000000   8.190000 (  8.188726)
rubinius 2.2.7 (2.1.0 build 2014-05-20 JI) [x86_64-linux-gnu]
 14.359762   0.003525  14.363287 ( 14.193565)
jruby 1.7.12 (2.0.0p195) 2014-04-15 643e292 on Java HotSpot(TM) 64-Bit Server VM 1.7.0_55-b13 [linux-amd64]
  4.570000   0.000000   4.570000 (  4.367000)

Как я и предполагал, JRuby является самым быстрым с 4.367000, чем Ruby с 8.188726 и последним Rubinius с 14.193565.

person mdesantis    schedule 05.06.2014
comment
почему Рубиний такой медленный? - person nurettin; 02.12.2016
comment
интересно было бы проверить сейчас - person mdesantis; 02.12.2016
comment
Еще один отличный инструмент, в котором есть нативные расширения, а не Windows: гем absolute_time. Тестовый интерфейс, но с использованием HPET внутри. - person ; 01.06.2018