Comparando a performance de implementações do Ruby (1.8 x 1.9 x JRuby x Rubinius)
Em primeiro lugar, nunca confie em testes de performance alheios por isso durante o post vou dar as ferramentas para que o leitor reproduza os testes no seu ambiente se assim o desejar.
Em segundo lugar a minha intenção não era fazer um teste abrangente, mas sim detectar diferenças de performance em um recurso bem específico: threads.
Antes de simplesmente jogar os resultados dos testes na tela, vejamos o que me levou a eles.
Aqui na empresa o Mailee trabalha fortemente com execução concorrente de código. A versão atual do nosso software de entrega implementa a concorrência com threads. Já considerei diversas vezes a migração para uma arquitetura multi-processo, idéia que ainda não foi descartada. No entanto, atualmente o trabalho para migrar para processos parece maior que o benefício, o que me fez pensar em otimizar o código e procurar uma boa implementação de threads em Ruby.
Os testes e o ambiente:
Bom, aos testes. O ambiente de testes utilizado foi um MacBook com processador Core 2 Duo de 2.4 GHz executando o Mac OS X 10.5.8, os resultados são a média de 10 execuções.
Realizei um teste para multi-threading limitado pelo IO (I/O bound) e um para multi-threading limitado pela CPU (CPU bound). Cada teste foi executado inicialmente com apenas um thread, e depois aumentando a carga de trabalho linear e uniformemente até 10 threads simultâneos. Abaixo o código dos testes:
Resultados:
Conclusões:
É curioso observar que embora o MRI 1.9.1 tenha melhorado drasticamente sua performance para os threads IO bound, quando o recurso é CPU ele fica parelho e um pouco pior comparado ao MRI 1.8.7.
A performance do jruby no teste de CPU me decepcionou, mas a lentidão pode ser relacionada a JVM do Mac OS X.
Pelos resultados apenas desses dois testes eu ficaria com o MRI 1.9.1 ou com o Rubinius. Mas é importante ressaltar que a versão 1.0 do Rubinius não é compatível com o Ruby 1.9, mas sim com o Ruby 1.8.
E não percam a seguir:
Ainda pretendo publicar um teste comparativo usando o conjunto de benchmarks diponível em http://github.com/acangiano/ruby-benchmark-suite, mas isso fica para um post futuro. No meu próximo post pretendo apresentar testes similares feitos com um código semelhante porém utilizando processos ao invés de threads.
