JVM, Portabilidade e Desempenho

outubro 11, 2007 às 10:51 am | Publicado em Java | Deixe um comentário

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.

Anúncios

Deixe um comentário »

RSS feed for comments on this post. TrackBack URI

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

Crie um website ou blog gratuito no WordPress.com.
Entries e comentários feeds.

%d blogueiros gostam disto: