Você parece estar fazendo duas perguntas bastante diferentes:
- O Java é realmente lento? Em caso afirmativo, por que?
- Por que o Java é percebido como lento, mesmo que seja mais rápido do que muitas alternativas?
A primeira delas é mais ou menos um tipo de pergunta "quanto tempo dura uma corda". Tudo se resume à sua definição de "lento". Comparado a um intérprete puro, o Java é extremamente rápido. Comparado a outras linguagens que são (normalmente) compiladas para algum tipo de código de código e compiladas dinamicamente para código de máquina (por exemplo, C # ou qualquer outra coisa no .NET), o Java é praticamente o mesmo. Comparado às linguagens normalmente compiladas em código de máquina puro e com equipes (geralmente grandes) de pessoas trabalhando apenas para melhorar seus otimizadores (por exemplo, C, C ++, Fortran, Ada), o Java se sai muito bem em algumas coisas, mas no geral tende a ser pelo menos um pouco mais lento.
Muito disso está relacionado principalmente à implementação - basicamente, tudo se resume ao fato de um usuário aguardar enquanto um compilador dinâmico / JIT é executado. Portanto, a menos que você tenha um programa que seja executado por um bom tempo, é É difícil justificar que o compilador gaste muito tempo em otimizações difíceis. Portanto, a maioria dos compiladores Java (e C # etc.) não se esforçam muito em otimizações realmente difíceis. Em muitos casos, trata-se menos de quais otimizações são feitas do que onde elas são aplicadas. Muitos problemas de otimização são NP completos, portanto, o tempo gasto aumenta rapidamente com o tamanho do problema sendo atacado. Uma maneira de manter o tempo dentro da razão é aplicar apenas a otimização a algo como uma única função de cada vez. Quando é apenas o desenvolvedor aguardando o compilador, você pode demorar muito mais tempo e aplicar a mesma otimização a partes muito maiores do programa. Da mesma forma, o código para algumas otimizações é bastante cabeludo (e, portanto, pode ser bem grande). Novamente, como o usuário está aguardando enquanto o código é carregado (e o tempo de inicialização da JVM geralmente é um fator significativo no tempo geral), a implementação precisa equilibrar o tempo economizado em um local versus perdido em outro - e considerando o pouco código se beneficia das otimizações peludas, manter a JVM pequena geralmente é mais benéfica.
Um segundo problema é que, com Java, você freqüentemente obtém um tipo de solução mais ou menos "tamanho único". Apenas por exemplo, para muitos desenvolvedores Java, o Swing é essencialmente a única biblioteca de janelas disponível. Em algo como o C ++, existem literalmente dezenas de bibliotecas, estruturas de aplicativos etc., cada uma com seu próprio conjunto de compromissos entre facilidade de uso x execução rápida, aparência consistente versus aparência nativa, e assim por diante. O único ponto de discórdia real é que alguns (por exemplo, Qt) podem ser bastante caros (pelo menos para uso comercial).
Terceiro, muito código escrito em C ++ (e C ainda mais) é simplesmente mais antigo e mais maduro. Muitas delas contêm um núcleo de rotinas escritas décadas atrás, quando gastar tempo extra otimizando o código era um comportamento normal e esperado. Isso geralmente tem um benefício real em códigos menores e mais rápidos. C ++ (ou C) recebe o crédito pelo código ser pequeno e rápido, mas é realmente muito mais um produto do desenvolvedor e as restrições de quando o código foi escrito. Até certo ponto, isso leva a uma profecia auto-realizável - quando as pessoas se preocupam com a velocidade, geralmente selecionam C ++ porque ela tem essa reputação. Eles investem tempo e esforço extras na otimização e uma nova geração de código C ++ rápido é gravada.
Para resumir, a implementação normal de Java torna a otimização máxima problemática, na melhor das hipóteses. Pior, onde Java é visível , coisas como kits de ferramentas de janelas e tempo de inicialização da JVM geralmente desempenham um papel maior do que a velocidade de execução da própria linguagem. Em muitos casos, C e C ++ também recebem crédito pelo que é realmente o produto de simplesmente trabalhar mais na otimização.
Quanto à segunda pergunta, acho que é em grande parte uma questão da natureza humana em ação. Alguns fanáticos fazem afirmações bastante infladas sobre o Java ser incrivelmente rápido. Alguém experimenta e descobre que mesmo um programa trivial leva alguns segundos para começar e se sente lento e desajeitado quando é executado. Poucos provavelmente se incomodam em analisar as coisas para perceber que grande parte disso é o tempo de inicialização da JVM e o fato de que, quando tentam, nada do código foi compilado ainda - parte do código está sendo interpretado, e alguns sendo compilados enquanto esperam. Pior, mesmo quando é executado com rapidez suficiente, a aparência e a aparência geralmente parecem estranhas e desajeitadas para a maioria dos usuários; portanto, mesmo que as medidas objetivas mostrem tempos de resposta rápidos, ainda pareceria desajeitado.
A adição desses elementos leva a uma reação bastante simples e natural: o Java é lento, feio e desajeitado. Dado o hype de dizer que é realmente rápido, há uma tendência a reagir exageradamente e concluir que isso é horrivelmente lento, em vez de um (mais preciso) "um pouco mais lento, e principalmente em circunstâncias específicas". Isso geralmente é o pior para um desenvolvedor que escreve os primeiros programas no idioma. A execução de um programa "olá mundo" na maioria dos idiomas parece instantânea, mas em Java há uma pausa facilmente perceptível quando a JVM é iniciada. Mesmo um intérprete puro que executa muito mais devagar em loops apertados e ainda assim parece mais rápido para códigos como esse, simplesmente porque ele pode ser carregado e começar a executar um pouco mais cedo.