Visite também: UnderLinux ·  VivaOLinux ·  LinuxSecurity ·  Dicas-L ·  NoticiasLinux ·  SoftwareLivre.org ·  [mais] ·  Efetividade ·  Linux in Brazil ·  Floripa  

Desempenho e portabilidade: GCJ, o compilador Java livre

Com a repercussão gerada quando a Sun resolveu disponibilizar o código fonte do Java, resolvi testar o Java Livre. O projeto GCJ da GNU é um compilador Java totalmente livre, onde o desenvolvedor pode gerar bytecode ou código binário nativo. Não sou especialista em Java, mas fiquei surpreso ao executar os testes mencionados neste artigo. Quero deixar bem claro que o objetivo deste documento não é gerar polêmica, muito menos classificar como melhor ou pior determinada tecnologia, e sim disponibilizar os teste efetuados na NETi TECNOLOGIA.” A nota foi enviada por Alessandro de Oliveira Faria (CABELO) (alessandrofariaΘnetitec·com·br), que acrescentou este link da fonte para maiores detalhes.

Comentários dos leitores

Os comentários abaixo são responsabilidade de seus autores e não são revisados ou aprovados pelo BR-Linux. Consulte os Termos de uso para informações adicionais. Esta notícia foi arquivada, não será possível incluir novos comentários.
Comentário de Paulo Pontes
sem swing?: gcj não tem suporte a swing, a única parte em que a ladainha do "java é lento" ainda guarda alguma verdade.

assim que o suporte a swing (ou mesmo a swt) for adicionado, acho que já vale a pena testar.
Comentário de acidbase
SWT: Certa vez eu vi o Eclipse sendo compilado e rodando com o GCJ. O Eclipse usa SWT (criado pelo próprio time que desenvolve o Eclipse) então eu *acho* que SWT já funcione com programas compilados pelo GCJ...

--
Osvaldo Santana Neto (aCiDBaSe)
Comentário de nemesis
RTFM?: vc chegou a ler o artigo, antes de armar a defesa?

a conclusão do teste com um programa compactador, sem Swing e que utiliza tanto algoritmos CPU-bound quanto uma boa dose de IO:


-----------------------------
! Execução ! Tempo !
! Java bytecode ! 24.482s !
! Código nativo ! 12.600s !
! gij bytecode ! 13.225s !
-----------------------------


os javalis gostam de dizer que o problema é o tempo de inicialização da JVM. Mas perceba que mesmo usando bytecodes com o interpretador gij ainda é mais rápido do que com a JVM!

let the flames begin!! :D

;; ((lambda (x) x) "Isto é um comentário e não será executado nunca")

Comentário de cesarse
Lembra "Get the facts"...: ... ou minhas dissertações da quinta série :^D
É cedo pra eu dar uma opinião, preciso chegar em casa e fazer o teste eu mesmo. IMHO, o artigo não é muito conclusivo.
Será que a versão da Sun é devagar por causa do acesso ao disco ou do acesso à memória (ou ambos)? Dois programas distintos deveriam ter sido feitos, um que só faz I/O e outro number crunch.
E quanto a outros aspectos como, por exemplo, concorrência? Provavelmente os métodos de se criar processos são distintos na JVM da Sun e na JVM da FSF. Qual é o mais eficiente?
É justo comparar o código nativo com o interpretado? Vai comparar com código em C compilado com -O2. :^)
Por último (isso não tem nada a ver com performance), código nativo não é portável. Use java e jogue o wine fora. :-D
Comentário de nemesis
pq?: "Dois programas distintos deveriam ter sido feitos, um que só faz I/O e outro number crunch."

pq? para ter uma performance teórica, fora da realidade?

"É justo comparar o código nativo com o interpretado?"

e que tal interpretado com interpretado? vide a JVM contra gij...

"código nativo não é portável. Use java e jogue o wine fora."

ora, e não é o que eles estão fazendo? usando Java?

Realmente, código nativo não é portável, mas código fonte é.

;; ((lambda (x) x) "Isto é um comentário e não será executado nunca")

Comentário de jose
Uél....: Pô Cabelo.

Primeiro sabemos que "...Quero deixar bem claro que o objetivo deste documento não é gerar polêmica...", não é suficiente. Ao passo que

"Imagine a portabilidade do Java junto a performance do compilador C."

está classificando um determinado conjunto como 'melhor'.

Até onde sei, a portabilidade do C é mais uma questão de programação do que linguagem. A performance depende de diversos fatores, e existe um tempo aceitável para a execução de um determinado programa. O simples fato de gerar código nativo não significa necessariamente que será mais rápido.

Mas parece 'o meu é mais rápido que o teu no caso x' e 'eu escrevo muito menos que o teu no caso y portanto sou mais produtivo' são as bolas da vez.

Aproveita e inclui um teste aí. Preciso encontrar os número primos entre 2 e 1.000.000. Não é necessário imprimir, apenas gerar uma matriz e dizer quantos foram encontrados. Se eu precisar saber qual é o 24.867º, a resposta deve estar na ponta da língua. Serve para outras linguagens também. ;-)

Aqui, retornou 78498 primos e o 'time' mostra:

0.02user 0.01system 0:00.03elapsed 92%CPU

Ah, e é linguagem interpretada. Mas aceito comparações com gcc -O3, por exemplo.

Comentário de cesarse
pq? para ter uma performance:
pq? para ter uma performance teórica, fora da realidade?

Não.
1) Para ser conclusivo (é claro que essa não foi a intenção do autor e ele deixa isso bem claro). A argumentação fica fraca do jeito que está.
2) QuickSort tem uma performance que - em média - é excelente, mas na teoria o MergeSort ganha. Você sempre tem que analisar o melhor caso, o pior e o médio. Simplesmente pra saber o que fazer em casos específicos.
3) O que é fora da realidade? Talvez seus programas Top10 tenham o perfil do código do artigo. :-) Mas em aplicativos como planilha, jogos, editores de texto, bem... carrega uma vez tudo pra memória e pronto (ignore uso de memória virtual). Acredito (baseado em absolutamente nada além da *minha* vivência com computadores) que memória é muito mais importante para performance em geral do que disco.

e que tal interpretado com interpretado? vide a JVM contra gij...

Aí pode. Mas o outro está de bicão.

ora, e não é o que eles estão fazendo? usando Java?

Java é muito mais do que a sintaxe. Se vira código nativo, não é Java.

Realmente, código nativo não é portável, mas código fonte é.

Geralmente. Mas o complicado são aqueles casos em que o programa deve ser alterado porque em uma arquitetura usa words de tamanho 16, outra de 32; ou porque em uma os bits mais significativos estão de um lado ou do outro; ou porque a quebra de linha tem um ou dois bytes, ou ainda porque pra separar diretórios um usa barra pra um lado, o outro usa barra pro outro, tem um terceiro que usa dois pontos...
Comentário de jose
Não sei quem é quem: neste tal de "Get the facts"

> "Use java e jogue o wine fora. :-D"

Faltou aqui o 'mas não esqueça de baixar e instalar a jvm' para o seu sistema operacional, senão o "Write once, run anywhere!" não é válido.
:P

Mas conheces "Write once compile everywhere!"?

Comentário de nemesis
hmm: "Para ser conclusivo... A argumentação fica fraca do jeito que está."

fraca pq? de que maneira ele seria "conclusivo"?

Como números mostrando a performance do mesmo programa java rodando nativamente, sob a JVM e sob gij podem não ser conclusivas? só na cabeça de quem quer pq quer mostrar que a JVM é melhor...

"QuickSort tem uma performance que - em média - é excelente, mas na teoria o MergeSort ganha."

e daí? é o *mesmo* programa, não é quicksort em um e mergesort em outro. querendo mudar de assunto, né? ;)

"Você sempre tem que analisar o melhor caso, o pior e o médio."

desculpas de quem quer tapar o sol com a peneira...

"O que é fora da realidade?"

o que vc propôs: testar apenas um processo IO-bound e outro apenas CPU-bound. Foi bem mais realista como ele fez: testando um programa que faz tanto IO quanto roda um pequeno algoritmo de compressão CPU-bound... como a maioria dos programas do mundo real...

"memória é muito mais importante para performance em geral do que disco."

independente, o *mesmo programa* Java, rodando na *mesma plataforma*, apresenta significativas alterações de performance.

"Aí pode."

e o que vc tem a dizer sobre a performance apresentada?

"Java é muito mais do que a sintaxe."

verdade: é um SO completo! :)

"Se vira código nativo, não é Java."

que conversa mais fiada! Seu código-fonte que gerou o binário não some de uma hora para a outra após a compilação, ok? Vc pode levá-lo para outra plataforma e compilá-lo lá. Foi assim que C alcançou a portabilidade que tem...

"Geralmente. Mas o complicado são aqueles casos em que o programa deve ser alterado porque em uma arquitetura usa words de tamanho 16, outra de 32; ou porque em uma os bits mais significativos estão de um lado ou do outro; ou porque a quebra de linha tem um ou dois bytes, ou ainda porque pra separar diretórios um usa barra pra um lado, o outro usa barra pro outro, tem um terceiro que usa dois pontos..."

ei, é um programa Java, esqueceu? não vai estar usando nada específico de plataforma que não da própria plataforma Java...

;; ((lambda (x) x) "Isto é um comentário e não será executado nunca")

Comentário de a2gs
Bem, antes de tudo, neste: Bem, antes de tudo, neste clima de 'o meu é melhor que o seu':
http://shootout.alioth.debian.org/

Agora:
é, acho certo o que vc disse! Que tal entao compararmos implementações do MESMO algoritmo XXX em linguagens diferentes?

Entao, no caso, vc escreveria em portugues-estruturado (ou qualquer coisa assim) o algoritmo e cada um implementa na sua linguagem.
Ai compilamos na mesma maquina e rodamos (com o mesmo ambiente).
Blz?

Nao adianta comparar o calculo do 394587' numero primo num algoritmo tosco feito em C contra a implementação de, digamos, Don Knuth, em VB. Concorda? Como vc disse, é uma questao de COMO se programa em C, e nao da linguagem em si. Apoiadissimo!
[]s
Comentário de nemesis
não se esqueçam: que no caso específico do exemplo do Cabelo, é o mesmo programa Java, na mesma plataforma. apenas compilado por métodos diferentes...

;; ((lambda (x) x) "Isto é um comentário e não será executado nunca")

Comentário de cesarse
fraca pq? de que maneira ele:
fraca pq? de que maneira ele seria "conclusivo"?

Ele sequer fala qual versão da jvm usou. É por isso que todo mundo mete o pau no "Get the facts". Eles comparam laranjas com bananas escondendo detalhes e fazendo parecer que laranjas e bananas são iguais, já que é tudo fruta. O link que o a2gs mandou matou a pau.
Tudo bem, eu acredito que o Cabelo não fez nenhuma sacanagem como carregar as bibliotecas do gij de um ramdisk e as bibliotecas da jvm de um disquete, mas concorde que se você esconde detalhes é fácil falar que um é melhor que outro.
O trabalho dele obviamente tem valor (e é divertido ficar discutindo), mas não dá pra ser visto com rigor.

só na cabeça de quem quer pq quer mostrar que a JVM é melhor

Não vou ficar ofendido pois obviamente isso não é dirigido a mim :-)
Lembra do meu primeiro post? "É cedo pra eu dar uma opinião, preciso chegar em casa e fazer o teste eu mesmo". Eu sei ser imparcial.

e daí? é o *mesmo* programa, não é quicksort em um e mergesort em outro. querendo mudar de assunto, né? ;)

Fugir?!? Nunca! Foi só um exemplo de como teoria importa.

Foi bem mais realista como ele fez: testando um programa que faz tanto IO quanto roda um pequeno algoritmo de compressão CPU-bound... como a maioria dos programas do mundo real...

Que programas? O grep? Leitura de disco é uma porcentagem mínima do tempo de execução de um programa. Na época do 286 quando o micro travava era só olhar pro led da HD e esperar ele apagar. Hoje em dia ele continua travando mas o led não acende. E não é porque queimou :-D

e o que vc tem a dizer sobre a performance apresentada?

A complexidade dos dois algoritmos é a mesma. Só muda a constante :-D

Seu código-fonte que gerou o binário não some de uma hora para a outra após a compilação, ok?

Posso inventar um compilador java em bash que converte o código para C e depois compila. Ainda vai ser java, já que o código fonte não vai sumir.

ei, é um programa Java, esqueceu? não vai estar usando nada específico de plataforma que não da própria plataforma Java...

Erro meu. Achei que quando você disse "código nativo não é portável, mas código fonte é" estava se referindo a qualquer coisa menos java

Comentário de nemesis
matou a pau?!: "O link que o a2gs mandou matou a pau."

esse computer language shootout existe há vários anos e tudo o que prova é que em um ambiente completamente irreal e fora-da-realidade, programas implementando algoritmos específicos -- sem usar toneladas de bibliotecas e sem mistura com IO -- rodam melhor em algumas implementações do que em outras.

"mas concorde que se você esconde detalhes é fácil falar que um é melhor que outro."

ok, vou te dar o benefício da dúvida quanto a esse detalhe. Que aliás, parece implicar que o lema do java completo deveria ser "Escreva uma vez, rode em qualquer lugar, com variados graus de performance"

"Leitura de disco é uma porcentagem mínima do tempo de execução de um programa."

mínima?! A não ser que os programas que vc faça sejam number-crunchers CPU-bound, como renderizadores 3D e outras aplicações de cálculo matricial, a maioria dos programas, principalmente comerciais, vai passar boa parte do tempo parada, fora da CPU, esperando por eventos de IO se concluirem -- isso engloba não apenas acessos a disco, mas também user-input em interfaces interativas ou comunicação em rede...

"A complexidade dos dois algoritmos é a mesma. Só muda a constante"

não disse nada.

"Posso inventar um compilador java em bash que converte o código para C e depois compila. Ainda vai ser java, já que o código fonte não vai sumir."

não disse nada. e se fizer isso vai se dar bem: vai ter o programa Java rodando em plataformas que em que a JVM não roda, graças à ampla portabilidade de C. É essa a estratégia adotada por alguns compiladores de outras linguagens, como GHC de Haskell...

;; ((lambda (x) x) "Isto é um comentário e não será executado nunca")

Comentário de cesarse
esse computer language:
esse computer language shootout existe há vários anos

Pô, só ouvi falar agora :-{

programas implementando algoritmos específicos

O algoritmo pouco importa, desde que seja o mesmo

sem usar toneladas de bibliotecas e sem mistura com IO

Será que o mundo está de cabeça pra baixo e só eu acho certo isso? Fazendo assim eles asseguram que a "largada" para diferentes programas seja praticamente na mesma "linha".
Tentar minimizar fatores externos (já que isolar é impossível) para não alterar o resultado de uma medição é comum em química, física, estatística... porque na computação não pode?

lema ... deveria ser "... rode em qualquer lugar, com variados graus de performance"

Opaaaa! Esqueça a parte do escreva uma vez. Então esse é o lema do firefox, do oracle, do jboss e qualquer outro programa que não seja exclusivo de uma única plataforma. Por que só implicam com java?

programas, principalmente comerciais, vai passar boa parte do tempo parada ... esperando por ... IO ... user-input ... comunicação em rede...

Bem, então para o usuário de editor de texto e instant messenger tanto faz se o programa é feito em Smalltalk ou diretamente em Assembly. Qualquer coisa mais rápida que um piscar de olhos está bom. No entanto jogos e programas gráficos têm prazer em devorar cpu e não disco. Talvez esse não tenha sido um argumento feliz porque foi muito restrito.

não disse nada.

Hmmm, não sabia se você tinha conhecimento de teoria de complexidade de algoritmos. Se tem, desculpe, vou tentar explicar grosseiramente (algum leitor talvez não faça idéia do que seja):
Dizer que um algoritmo tem o tempo de execução proporcional ao quadrado do tamanho da entrada significa que se a entrada de um programa for, digamos, 10 então o tempo de execução vai ser 100. Portanto, se eu apenas dobrar o tamanho da entrada, quadruplico o tempo de processamento. Além disso, se uma versão tem complexidade quadrática e outra tem complexidade quadrática mais uma constante (não importando se essa constante vale 1 zilhão) então os dois são equivalentes.
Eu quis dizer que os dois, no fundo, levam praticamente o mesmo tempo.


se fizer isso vai se dar bem: vai ter o programa Java rodando em plataformas que em que a JVM não roda

Então eu posso fazer um "compilador" de português estruturado e falar que a performance dele - para algumas coisas - é superior da de java? Isso é trapaça :-D

JVM não roda, graças à ampla portabilidade de C

C não é portável. Não sem esforço do programador para encapsular todas as idiossincrasias da plataforma. Além dos exemplos dados no post anterior, dá pra citar ainda diferenças semânticas, por exemplo:
return 1; significa que o programa deu erro em *nix, mas deu certo se for VMS.
E se você falar que java tem problemas parecidos, eu concordo 100%, mas digo que esses detalhes ficam por conta da jvm, não do programador.

O mesmo bytecode tem diferenças de performance se usarmos a jvm da sun de duas versões distintas (as mais novas são mais rápidas), que dirá usar jvm´s de dois fornecedores distintos!
Por último - e isso eu falo por experiência própria - quando abro meu eclipse usando a jvm dá tempo de tomar um café expresso. Se usar a gij, dá tempo de coar o café. :-D :-D :-D
Comentário de Emanuel San
Faltou o Java da IBM: Fiz os testes na minha máquina usando o programa Zipando.java disponibilizado pelo CABELO e consegui os seguintes resultados:


IBM Java 1.5.0 12.573s
GCJ 4.1.1-1.fc5 12.901s
GIJ 4.1.1-1.fc5 13.228s
Sun Java 1.5.0.07 19.173s


Meu arquivo tst.mpg tinha 100M. Refiz cada teste várias vezes e peguei o melhor resultado de cada. Olha que surpresa! O JIT que vem no JDK da IBM parece muito bom.

Comentário de Leidson Campos
Matou a pau: Bom esse teste do Emanuel Sam acabou de matar a discussão entre o Nemesis e o Cesarse e o vencedor foi ........... IBM JVM !!!


Leidson Campos
PlanetaMessenger.org
Comentário de nemesis
e eu matei a charada!: dêem uma olhada:

http://sourceforge.net/projects/jazzlib/

aparentemente, o pacote java.util.zip é nada mais que um thin wrapper para a boa e velha zlib nativa de guerra. Portanto, não é exatamente uma boa maneira de se testar a performance do java, dado que a parte do programa que está realmente fazendo todo o trabalho é uma biblioteca nativa.

Dito isso, acredito que a razão para a performance da JVM da IBM deve estar relacionado a um melhor mecanismo JNI para invocar chamadas de sistema nativas.

mas, claro, ainda não vai ser tão rápido quanto um programa nativo fazendo as chamadas diretamente à zlib... :)

a maneira mais direta para testar é zipar o mesmo arquivo na mesma máquina, usando a JVM IBM, a compilaçã GCJ, a interpretação GIJ, a JVM Sun e, por fim, um compactador nativo usando a zlib, como o bom e velho gzip ou ainda zip. ganha um doce quem adivinhar qual vai ganhar... ;)

;; ((lambda (x) x) "Isto é um comentário e não será executado nunca")

BR-Linux.org
Linux® levado a sério desde 1996. Notícias, dicas e tutoriais em bom português sobre Linux e Código Aberto. "A página sobre software livre mais procurada no Brasil", segundo a Revista Isto É.
Expediente
Sobre o BR-Linux
Enviar notícia ou release
Contato, Termos de uso
FAQ, Newsletter, RSS
Banners e selos
Anunciar no BR-Linux
BR-Linux apóia
LinuxSecurity, Tempo Real
Suporte Livre, Drupal
Verdade Absoluta
Pandemonium
Efetividade, Floripa.net
sites da comunidade
Ajuda
Moderação
Flames: não responda!
Publicar seu texto
Computador para Todos
Notícias pré-2004
Tutoriais, HCL pré-2004