[resolvido]Como o Java pode ser tão rapido rodando em JVM?

9 respostas
D

Eu fiz um programa com o propósito de ele exigir muito do PC devido a uma série de calculos matemáticos por tentativa e erro para resolver um sistema de ecuação de 8 variáveis e usei propositalmente uma metodologia para ficar lento, ele foi feito em Java e C++. Mesmo com uma série de calculos, só consegui perceber diferenças no tempo que ele levou para fazer todas as quelas operações usando cronometro. A "olho nú" não se percebe nada de diferente no tempo de resposta.

A questão é como uma linguagem compilada/interpretada pode ser quase tão rápida quanto uma compilada e linkeditada???

package exercfib;
import java.util.Scanner;


public class exercfic {


    
    public static void main(String[] args) {

        Scanner input = new Scanner( System.in);

        int e1, e2,e3,e4,e5,e6,e7,e8;
        int i;
        int [] ppp={0,0,0,0,0,0,0,0};
        int [] l1={0,0,0,0,0,0,0,0};
        int [] l2={0,0,0,0,0,0,0,0};
        int [] l3={0,0,0,0,0,0,0,0};
        int [] l4={0,0,0,0,0,0,0,0};
        int [] l5={0,0,0,0,0,0,0,0};
        int [] l6={0,0,0,0,0,0,0,0};
        int [] l7={0,0,0,0,0,0,0,0};
        int [] l8={0,0,0,0,0,0,0,0};

        ppp[0]=-13;
        ppp[1]=61;
        ppp[2]=39;
        ppp[3]=38;
        ppp[4]=10;
        ppp[5]=51;
        ppp[6]=15;
        ppp[7]=26;



System.out.print("ATENÇÃO,ANTES DE TUDO *NÃO* TENHO CERTESA!!!\n");

          for(i=0;i<=7;i++){

            System.out.print("digite a o valor da linha 1 e coluna:  "+ (i+1)+ " ");
            l1[i]=input.nextInt();
        }
          for(i=0;i<=7;i++){

            System.out.print("digite a o valor da linha 2 e coluna:  "+ (i+1)+ " ");
            l2[i]=input.nextInt();
        }
         for(i=0;i<=7;i++){

            System.out.print("digite a o valor da linha 3 e coluna:  "+ (i+1)+ " ");
            l3[i]=input.nextInt();
        }
         for(i=0;i<=7;i++){

            System.out.print("digite a o valor da linha 4 e coluna:  "+ (i+1)+ " ");
            l4[i]=input.nextInt();
        }
         for(i=0;i<=7;i++){

            System.out.print("digite a o valor da linha 5 e coluna:  "+ (i+1)+ " ");
            l5[i]=input.nextInt();
        }
         for(i=0;i<=7;i++){

            System.out.print("digite a o valor da linha 6 e coluna:  "+ (i+1)+ " ");
            l6[i]=input.nextInt();
        }
         for(i=0;i<=7;i++){

            System.out.print("digite a o valor da linha 7 e coluna:  "+ (i+1)+ " ");
            l7[i]=input.nextInt();
        }
         for(i=0;i<=7;i++){

            System.out.print("digite a o valor da linha 8 e coluna:  "+ (i+1)+ " ");
            l8[i]=input.nextInt();
        }


         for(i=0;i<=7;i++){

             System.out.print("digite o RESULDADO!!!! da linha: "+ (i+1)+ " ");
             ppp[i]= input.nextInt();
         }

//Daqui para baixo que comessou o teste de tempo.

        for(int x1=0; x1<=10; x1++){
          for(int x2=0; x2<=10; x2++){
             for(int x3=0; x3<=10; x3++){
               for(int x4=0; x4<=10; x4++){
                 for(int x5=0; x5<=10; x5++){
                   for(int x6=0; x6<=10; x6++){
                       for(int x7=0; x7<=10; x7++){
                            for(int x8=0; x8<=10; x8++){
                                e1=(l1[0]*x1)+(l1[1]*x2)+(l1[2]*x3)+(l1[3]*x4)+(l1[4]*x5)+(l1[5]*x6)+(l1[6]*x7)+(l1[7]*x8);
                                e2=(l2[0]*x1)+(l2[1]*x2)+(l2[2]*x3)+(l2[3]*x4)+(l2[4]*x5)+(l2[5]*x6)+(l2[6]*x7)+(l2[7]*x8);
                                e3=(l3[0]*x1)+(l3[1]*x2)+(l3[2]*x3)+(l3[3]*x4)+(l3[4]*x5)+(l3[5]*x6)+(l3[6]*x7)+(l3[7]*x8);
                                e4=(l4[0]*x1)+(l4[1]*x2)+(l4[2]*x3)+(l4[3]*x4)+(l4[4]*x5)+(l4[5]*x6)+(l4[6]*x7)+(l4[7]*x8);
                                e5=(l5[0]*x1)+(l5[1]*x2)+(l5[2]*x3)+(l5[3]*x4)+(l5[4]*x5)+(l5[5]*x6)+(l5[6]*x7)+(l5[7]*x8);
                                e6=(l6[0]*x1)+(l6[1]*x2)+(l6[2]*x3)+(l6[3]*x4)+(l6[4]*x5)+(l6[5]*x6)+(l6[6]*x7)+(l6[7]*x8);
                                e7=(l7[0]*x1)+(l7[1]*x2)+(l7[2]*x3)+(l7[3]*x4)+(l7[4]*x5)+(l7[5]*x6)+(l7[6]*x7)+(l7[7]*x8);
                                e8=(l8[0]*x1)+(l8[1]*x2)+(l8[2]*x3)+(l8[3]*x4)+(l8[4]*x5)+(l8[5]*x6)+(l8[6]*x7)+(l8[7]*x8);

if((ppp[0]==e1) && (ppp[1]==e2)&& (ppp[2]==e3) && (ppp[3]==e4) && (ppp[4]==e5) &&(ppp[5]==e6) && (ppp[6]==e7) && (ppp[7]==e8)){

    System.out.print("o valor é:"+ x1+ " "+ x2+ " "+ x3+ " "+ x4+ " "+ x5+ " "+ x6+ " "+ x7+ " "+ x8+ " ");

}

                            }


        }


        }


        }

        }

        }

        }

        }



    }

9 Respostas

Alexandre_Saudate

Já ouviu falar do HotSpot ? É uma feature embutida na JVM que checa o código. Se um mesmo código é executado muitas vezes, ele traduz para código nativo.

[]´s

maior_abandonado

para este tipo de coisa a JVM faz uma serie de otimizações… o que me parece que java é mais lento mesmo que código nativo são operações com IO…

tipo, daria para pegar para testar, ler um arquivo texto grande, 10 vezes, em c++ e java, ai acho que ja da uma diferença mais humanamente visivel… ou ao menos acho que ja daria para notar…

D

asaudate:
Já ouviu falar do HotSpot ? É uma feature embutida na JVM que checa o código. Se um mesmo código é executado muitas vezes, ele traduz para código nativo.

[]´s

Bem explicado…

Eu tive de fazer este programa pois meu professor pedil para resolver um sistema de equações e como sou péssimo em matrizes, resolvi utilizar esta “gambiarra”, e obvio que mandei esta “solução” para meus amigos…

maior_abandonado:
para este tipo de coisa a JVM faz uma serie de otimizações… o que me parece que java é mais lento mesmo que código nativo são operações com IO…

tipo, daria para pegar para testar, ler um arquivo texto grande, 10 vezes, em c++ e java, ai acho que ja da uma diferença mais humanamente visivel… ou ao menos acho que ja daria para notar…

Vou depois tentar isto.

E obrigado por explicarem o hotSpot e otimizações.

ViniGodoy

Dá uma lida:




São artigos ótimos sobre o assunto.

ViniGodoy

Uma dica, não coloque println no meio de sua computação que será medida.
O println acessa o console, que é extremamente lento.

A performance de I/O do java é muito eficiente se você utilizar a biblioteca java.nio.

Ah, também vale a pena lembrar que mesmo o bytecode sendo teoricamente interpretado, ele ainda é centenas de vezes mais rápido que as linguagens interpretadas comuns. Ele é um arquivo binário, compilado para a VM, que o executa diretamente, sem grandes necessidades de interpretação ou sem grandes preocupações com erros de sintaxe.

A ergonomia das linguagens virtualizadas (como o Java) e de uma linguagem compilada é completamente diferente. De fato, há situações em que o Java irá superar o desempenho do C++. Em outras, o C++ irá ganhar em larga escala do java.

Finalmente, quando se fala de performance, é bom lembrar que os gargalos de processamento irão estar mais provavelmente em I/O ou em algoritmos mal implementados, não tanto na velocidade da linguagem em si. Não é à toa que vemos sites em PHP com um tempo de resposta excelente.

foxpv

asaudate:
Já ouviu falar do HotSpot ? É uma feature embutida na JVM que checa o código. Se um mesmo código é executado muitas vezes, ele traduz para código nativo.

[]´s

Exatamente, e é o JIT Compiler que faz esse trabalho de compilar para código nativo!

quebrado

Depois falam que a linguagem vai morrer!

J

Respondendo ao autor do tópico e desmistificando várias coisas.

1) c++ é mais rápido que java ou c#?
Sim, por uma questão de magnitude, ou seja, type safe não vem de graça, e o custo da segurança é a perda de desempenho.

ex:
um metodo que copia um vetor.

jCopyarray(T[] source, t[] dest){
      // outros métodos aqui checarão a segurança dos dados e da cópia
}


  CppCopyarray(T* source, t* dest){
      // não existem métodos que checarão a segurança, sendo que ponteiros podem enxergar uma área larga de memória,
// enquanto t[indice] enxerga apenas um offset
}

Acima mostra o que eu quero dizer com magnitude(quantidade de código gerado).

2) Um software java ou c# pode ser mais rápido que um c++?
Sim, porque gerenciar memória manualmente não é uma tarefa fácil, especialmente quando o projeto cresce em larga escala. Qualquer falha no gerenciamento pode ocasionar uma perda terrível no desempenho, tanto no custo de memória com leaks, quanto ao custo de processamento, praticamente inundando o processador. Java e c# na maioria dos casos podem ser 90% mais rápidos que c++, porque é muito mais fácil criar um bom software java ou c#, do que um bom software c++.

3) A culpa do desempenho de um software é da linguagem?
Não, a culpa é do algoritmo mal escrito. O tamanho do código é proporcional ao tamanho do desempenho, e mesmo o hotspot ou a clr não vão sanar esse problema. Com relação ao c++, o hostpot pode otimizar o algoritmo mal escrito em java, mas o resultado não é realmente "ótimo". Um bom algoritmo escrito em c++ é praticamente invencível de se bater com compilações dinamicas, e a mesma coisa com assembly, pelas razões da magnitude.

4) Em qual tipo de aplicação podemos perceber falhas de algoritmos?
Em aplicações de tempo real, como jogos, programas de segurança como dvrs. Em jogos e aplicações de vídeo segurança, qualquer latência de ms poderia gerar um transtorno para quem joga(leg), e para aplicação de segurança, isso poderia gerar um prejuízo de milhões em caso de roubo, pois a latência não permitiu que a cena fosse capturada.

Obs - HotSpot - (Corrigindo, não só compiladores dinâmicos mas uma série de outras tecnologias usada na jvm). Então uma vez que um bytecode roda na jvm ele é compilado e otimizado para o processador real(compilação dinâmica). Isso acontece a todo instante, durante a execução do código.

http://java.sun.com/javase/technologies/hotspot/index.jsp

Marck
juliocbq:
Respondendo ao autor do tópico e desmistificando várias coisas.

1) c++ é mais rápido que java ou c#?
Sim, por uma questão de magnitude, ou seja, type safe não vem de graça, e o custo da segurança é a perda de desempenho.

ex:
um metodo que copia um vetor.

jCopyarray(T[] source, t[] dest){
      // outros métodos aqui checarão a segurança dos dados e da cópia
}


  CppCopyarray(T* source, t* dest){
      // não existem métodos que checarão a segurança, sendo que ponteiros podem enxergar uma área larga de memória,
// enquanto t[indice] enxerga apenas um offset
}

Acima mostra o que eu quero dizer com magnitude(quantidade de código gerado).

2) Um software java ou c# pode ser mais rápido que um c++?
Sim, porque gerenciar memória manualmente não é uma tarefa fácil, especialmente quando o projeto cresce em larga escala. Qualquer falha no gerenciamento pode ocasionar uma perda terrível no desempenho, tanto no custo de memória com leaks, quanto ao custo de processamento, praticamente inundando o processador. Java e c# na maioria dos casos podem ser 90% mais rápidos que c++, porque é muito mais fácil criar um bom software java ou c#, do que um bom software c++.

3) A culpa do desempenho de um software é da linguagem?
Não, a culpa é do algoritmo mal escrito. O tamanho do código é proporcional ao tamanho do desempenho, e mesmo o hotspot ou a clr não vão sanar esse problema. Com relação ao c++, o hostpot pode otimizar o algoritmo mal escrito em java, mas o resultado não é realmente "ótimo". Um bom algoritmo escrito em c++ é praticamente invencível de se bater com compilações dinamicas, e a mesma coisa com assembly, pelas razões da magnitude.

4) Em qual tipo de aplicação podemos perceber falhas de algoritmos?
Em aplicações de tempo real, como jogos, programas de segurança como dvrs. Em jogos e aplicações de vídeo segurança, qualquer latência de ms poderia gerar um transtorno para quem joga(leg), e para aplicação de segurança, isso poderia gerar um prejuízo de milhões em caso de roubo, pois a latência não permitiu que a cena fosse capturada.

Obs - HotSpot - Compilador de bytecode para instruções nativas. Então uma vez que um bytecode roda na jvm ele é compilado e otimizado para o processador real(compilação dynamica). Isso acontece toda vez que o software é executado.

Ótima explicação!

Criado 21 de maio de 2010
Ultima resposta 21 de mai. de 2010
Respostas 9
Participantes 8