JVM, Portabilidade e Desempenho

Outubro 11, 2007 at 10:51 am | In Java | Leave a Comment

Quem desenvolve sabe que um dos pontos fortes da tecnologia Java é ser multi-plataforma, ou seja, o mesmo código pode rodar sem problemas em um ambiente unix, windows, etc. Essa portabilidade é garantida graças a sofisticada JVM (Java Virtual Machine).

Ao contrário de linguagens como o C, onde o compilador gera um executável para uma máquina específica, o compilador Java gera um executável (.class) para uma máquina genérica, a JVM. O papel da JVM é executar este .class em uma plataforma específica.

Durante a interpretação do bytecode (conteúdo do arquivo .class), a JVM pode encontrar possíveis trechos que estão sendo executados muitas vezes (pontos quentes), por exemplo um laço for ou uma chamada recursiva. Para melhorar a execução destes pontos quentes, entra em campo o JIT, um compilador Just in Time. Estes trechos são compilados para código de máquina e mantidos em memória para possíveis chamadas.

Essa compilação dinâmica é a grande “sacada” da JVM. Ela é muito otimizada, pois leva em consideração dados sobre a execução real do programa.

Vamos a uma pequena comparação com a linguagem C. Vamos utilizar como exemplo o algoritmo de recursividade que o Paulo Silveira mostrou aqui. O clássico problema de fibonacci. Neste exemplo fica claro o funcionamento do compilador JIT.

Vamos ver o código em Java:

java.jpg

Compile a classe: javac Teste.java

Para executar: java Teste <parametro>

Ex: Para calcular o fibonacci de 10 –> java Teste 10

O mesmo código em C:

c_fibo.jpg

Estou usando o compilador gcc, para compilar use: gcc <nomeArquivo>.c -o Teste

Para executar (em ambiente linux), certifique-se que esteja no diretório do arquivo e digite: ./ Teste <parametro>

Ex: Para calcular o fibonacci de 10 –> ./Teste 10

—–

Agora vamos comparar a execução das duas implementações (o tempo foi medido utilizando o comando time do linux):

Fibonacci de 10:

  • java = 0.048 segundos
  • c = 0.000 segundos (praticamente nada)

O programa feito em C foi bem mais rápido.

Fibonacci de 30:

  • java = 0.180 segundos
  • c = 0.064 segundos

Veja que o Java agora já melhorou um pouco. Ficou 3x mais lento que o C.

Fibonacci de 46:

  • java = 38.006 segundos
  • c = 42.471 segundos

Agora o Java foi mais de 4 segundos mais rápido. Tudo isso graças ao compilador JIT, que agiu em cima da hora para garantir o desempenho do código.

—-

Você pode acompanhar a compilação do JIT utilizando o parâmetro: -XX:+PrintCompiliation. Ex:

time java -XX:+PrintCompilation Teste 46
1 java.lang.String::hashCode (60 bytes)
2 java.lang.String::charAt (33 bytes)
3 ! sun.nio.cs.UTF_8$Encoder::encodeArrayLoop (698 bytes)
4 Teste::fibo (32 bytes)

Perceba que além do método fibo, o JIT compilou o método hashCode e charAt da classe String.

Interessante não??? Fique esperto quando alguém disser que Java é mais lento que C. Em algumas situações o Java leva a melhor.

Além do JIT, a JVM possui outras características interessantes. Falaremos disso em outros artigos.

Sem comentários ainda »

Feed RSS dos comentários deste post URI do TrackBack

Deixe um comentário

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Blog no WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.