Página Inicial > java > Performance no Java

Performance no Java

30, Novembro, 2007

Todos desejamos performance nas nossas aplicações. No Java e apesar de alguns dizerem que é mais rápido que C++ isto nem sempre é verdade, mas vou falar disso noutra altura. Hoje o que queria colocar aqui é uma ajuda para quem tem que trabalhar com Java. Em vez de correr a JVM client o melhor para performance é mesmo correr a JVM server. Para isso terá que utilizar o terminal e correr os programas da seguinte forma:

java -server -jar programa.jar

Ora para não ter que andar sempre a adicionar -server no terminal, o melhor é colocar o -server como default. Para isso basta editar o ficheiro jvm.cfg (que é um ficheiro de texto simples) e onde está:

-client KNOWN
-server KNOWN

é só trocar a ordem para:

-server KNOWN
-client KNOWN

Assim tudo o que for java vai correr na JVM server e só se chamarmos explicitamente a versão client é que será corrida aí.

Ganhos de performance? Sim bastante notáveis. Estive a experimentar calcular uma série de Fibonacci e posso dizer que o tempo de execução foi em média:

-client: 540ms
-server: 397ms

o que dá para o mesmo programa um ganho de 143ms ou cerca de 26%, nada mau. O downside? Tradicionalmente o JVM -server demora um pouco mais a arrancar e come mais memória, mas se depois se tornar mais rápido... para quê queixarmo-nos...

no Mac OS X Tiger o jvm.cfg está em
/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home/lib/jvm.cfg

Bem, por curiosidade o mesmo cálculo em C sem optimizações demorou 810ms e com optimizações -O3 cerca de 260ms. Mas como disse estas discussões são para outra altura.

java

  1. 30, Novembro, 2007 a 10:34 | #1

    Viva,

    Outra coisa fácil de configurar e que costuma resultar em ganhos na performance é o tamanho inicial e maxímo da heap, para isso basta-​​te configurar –Xms (initial heap size) e –Xmx (maximum heap size). Podemos assim evitar que o GC entre em acção mesmo quando existe memória que poderia ser usada pela JVM.

    Poderias também entrar em assuntos como o tunning do GC, mas isso é daquelas “artes mágicas” algo complexas (pelo menos eu acho, mas também não sei assim tanto sobre o assunto) que ou sabemos realmente o que estamos a fazer ou então em vez de melhorarmos pioramos a performance.

    Ah já agora, talvez já saibas mas fica aqui a dica, a JVM possui um profiler muito simples que podes usar quando estás a fazer estes testes, o JConsole. Para o usares basta começares a jvm com mais um switch: –Dcom.sun.management.jmxremote. Depois enquanto o programa java estiver a correr, basta lançares o jconsole (que está no $JAVA_​HOME/​bin).

  2. 30, Novembro, 2007 a 10:36 | #2

    A server-​​vm tem uma melhor performance do que a client-​​vm, mas o consumo de memória (que pode ser muito maior) e o tempo extra de arranque das aplicações pode negar esse ganho. Para aplicações que vão correr durante muito tempo, praticamente sozinhas, numa máquina com memória em grande quantidade, a server-​​vm é claramente melhor.

    Para aplicações desktop, se calhar não. Ganhas na performance das aplicações Java, e perdes no resto do sistema. Para o utilizador é capaz de ficar tudo na mesma.

  3. 30, Novembro, 2007 a 11:15 | #3

    O Carlos tem toda a razão.

    Que tal colocares o resultado do:
    time java –server aplicacao
    time java –client aplicacao

  4. 30, Novembro, 2007 a 12:39 | #4

    Pois, eu digo isso, performance vem à custa de recursos. Não há volta a dar-​​lhe. Ou se tem ou não se tem. Agora se alguém se dá ao trabalho de editar um ficheiro de configuração de JVM provavelmente é porque utiliza aplicações Java mais do que o simples applet ocasional. A meu ver quem estiver todo o dia enfiado num eclipse ou netbeans ou … etc… se calhar já começa a compensar a mudança. No caso do Netbeans 6 RC posso dizer que a diferença é notória.

    Claro que é preciso ter recursos, mais uma vez, não se fazem omoletes sem ovos.

  5. 30, Novembro, 2007 a 12:43 | #5

    @Gustavo,

    Os resultados que pedes estão lá escritos no post. Ou será que não leste bem?

    Desculpa, os valores lá não eram do time… mas cá vão..

    –Client

    real 0m0.667s
    user 0m0.610s
    sys 0m0.038s

    –Server

    real 0m0.569s
    user 0m0.506s
    sys 0m0.042s

    Estes valores foram corridos hoje, apenas uma vez com uma série de tralhada diferente… mas mesmo assim continua a ver-​​se melhorias da versão server.

  6. 30, Novembro, 2007 a 15:20 | #6

    To David: Está visto que não me fiz perceber. Por isso vou tentar outra vez e até incluo código:
    public class Primos {

    public static void main(String[] args) {

    int n = 100000;
    boolean primo;
    int i,z;
    long inicio, fim;
    inicio = System.currentTimeMillis();
    for (i = 1; i <= n; i++) {
    primo = true;

    for(z = 2 ; z <= i/​2 && primo; z++ ){

    if(i%z == 0)
    {
    primo=false;
    }
    }
    }
    fim = System.currentTimeMillis();
    System.out.println(“Demorou ” + (fim-inicio)/(float)1000 + ” segundos de tempo total.”);

    }
    }

    Este código vai indicar o tempo que a JVM esteve efectivamente a trabalhar. Comparar os outputs com –client e –server vai mostrar se existe um aumento de performance.
    Ao usar o “time java –client Primos” e “time java –server Primos” vai nos mostrar o overhead no arranque da JVM. Os tempos que tu indicas devem ser apenas os reportados pela aplicação.

  7. 30, Novembro, 2007 a 16:10 | #7

    @Gustavo,

    Os tempos do post são os dados pelo programa tal e qual como no teu exemplo.

    Os tempos do meu comentário são os da utilização do time java…

  8. 30, Novembro, 2007 a 19:46 | #8

    O problema destes “benchmarks” sintéticos é que o processamento é demasiado focado para se conseguir tirar conclusões válidas. Os testes correm durante pouquíssimo tempo, não geram grandes alocações de memória, e resumem-​​se a umas quantas linhas de código que, com um pouco de sorte, uma vez JITadas cabem dentro da cache do CPU.

    Porque como eu dizia, se tens um Eclipse a consumir quantidades obscenas de memória, e tens um Firefox ao lado com algumas tabs e mais uma coisa ou outra e não tens 4Gb de RAM, se calhar vais começar a usar swap, quando com a client VM cabe tudo na memória e a perda de performance não se nota (porque a aplicação passa a maior parte do tempo à espera de input).

Comentários encerrados.
Get Adobe Flash playerPlugin by wpburn.com wordpress themes