Como Rubinius e JRuby podem ser tão lentos?
-
21-12-2019 - |
Pergunta
Decidi ver quanto tempo levaria para iterar uma série de hashes.Abaixo está o código:
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
O tempo é calculado subtraindo o tempo atual após o loop do tempo atual antes do loop.
Este foi o tempo que o cálculo demorou no YARV 2.1.1, de acordo com a matemática do código:
0.001962017
Veja quanto tempo demorou no Rubinius 2.2.6:
0.022598
E jRuby 1.7.12
0.022317
Supostamente Rubinius e jRuby têm vantagens de desempenho em relação ao YARV.Por que eles levam quase 12 vezes mais tempo para realizar a mesma operação básica?Isso é normal ou tenho algo configurado incorretamente?
Solução
Você está comparando tempos muito pequenos, que são comprometidos pelo carregamento do ambiente.Na minha experiência, para ter benchmarks confiáveis você precisa obter tempos de pelo menos 10 segundos, para mitigar os tempos de aquecimento.Cerca de 10 segundos espero que JRuby tenha o melhor desempenho, seguido por Ruby e Rubinius.
Vamos ver:
# 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
Esta é a saída na minha máquina (eu uso fish shell + rbenv, você deve escrever seu próprio script):
> 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)
Como eu supunha, JRuby é o mais rápido com 4,367000, depois Ruby com 8,188726 e por último Rubinius com 14,193565.