Por que o Python é mais lento que Java, mas mais rápido que PHP [fechado]

17

Já vi várias referências que mostram o desempenho de vários idiomas em uma determinada tarefa.

Esses benchmarks sempre revelam que o Python é mais lento que o Java e mais rápido que o PHP, e me pergunto por que é esse o caso.

  • Java, Python e PHP são executados dentro de uma máquina virtual
  • Todos os três idiomas convertem seus programas em códigos de bytes personalizados executados no SO - portanto, nenhum deles é executado de forma nativa
  • Java e Python podem ser "compilados" ( .pycpara Python), mas o __main__módulo para Python não é compilado

Python e PHP são digitados dinamicamente e Java estaticamente - é por isso que o Java é mais rápido e, nesse caso, explique como isso afeta a velocidade.

E, mesmo que o argumento dinâmico versus estático esteja correto, isso não explica por que o PHP é mais lento que o Python - porque ambos são linguagens dinâmicas.

Você pode ver alguns benchmarks aqui e aqui e aqui

codificador de árvore
fonte
Em relação ao Python x PHP: é apenas uma questão de qualidade de implementação, provavelmente.
Charles Salvia
8
@ good_computer A maioria dos benchmarks é muito ruim. Houve outro recente (acho que você não vinculou) que a maioria das pessoas que o revisou reclamou que o idioma que afirmava ser "mais rápido" simplesmente possuía o melhor código otimizado. Isso geralmente é feito inconscientemente por alguém não tão familiarizado com os idiomas que acabam sendo considerados "lentos", para que eles não percebam que estão escrevendo um código melhor nos que consideram "rápidos".
Izkata
@ good_computer Parece-me que você está reivindicando alguma coisa, pois sua pergunta inclui o texto " Sempre esses benchmarks revelam que o Python é mais lento que o Java e mais rápido que o PHP " e " PHP é mais lento que o Python ". Remover essas aspas e reformular a questão como agnóstico da linguagem pode fazer com que seja reaberto.
Briddums
Esta questão é realmente tendenciosa : (1) referindo-se a benchmarks não autoritativos conduzidos em código ingênuo e não otimizado, escrito por programadores iniciantes em linguagens que eles não dominam (como dissecados nos respectivos tópicos de comentários) e (2) construídos sobre conceitos errôneos sobre linguagens interpretadas / bytecode (php / python são interpretados, arquivos de cache python codificados por java são árvores de sintaxe abstratas, não bytecode) e o estado das três linguagens (existem versões compiladas de python e php - as python são mais maduras, compiladas Porém, o php roda o facebook)
ZJR 16/11

Respostas:

26

O código da JVM pode ser compilado com JIT com eficiência, usando um compilador ad hoc trivial (e rápido). Mas o mesmo seria excepcionalmente difícil para PHP e Python, devido à sua natureza dinamicamente digitada. A JVM se traduz em um código nativo simples e de nível bastante baixo, bastante semelhante ao que um compilador C ++ produziria, mas para os idiomas dinâmicos você teria que gerar despacho dinâmico para literalmente todas as operações básicas e todas as chamadas de método. Esse despacho dinâmico é o principal gargalo de todos os idiomas desse tipo.

Em alguns casos, é possível eliminar o despacho dinâmico (bem como as chamadas virtuais em Java) usando um compilador JIT de rastreamento muito mais complicado. Essa abordagem ainda está em sua infância, não fazendo muita interpretação abstrata, e esse compilador provavelmente engasgará com as evalchamadas (que são muito típicas para as linguagens dinâmicas).

Quanto à diferença entre Python e PHP, o último é de qualidade muito inferior. Poderia correr mais rápido em teoria, mas nunca funcionará.

SK-logic
fonte
1
Por que o JIT é "excepcionalmente difícil" para idiomas dinâmicos? Veja a v8 ou o TraceMonkey no mundo do JavaScript - o JIT funciona bem.
treecoder
6
@good_computer, o rastreamento de JITs é notavelmente mais complexo que o normal, JITs ad hoc, e ainda está apresentando um desempenho muito mais lento do que JITs para os idiomas estaticamente tipados. Um JIT de rastreamento adequado envolveria uma interpretação abstrata completa e sufocaria em cada evalchamada.
SK-logic
2
Há provavelmente uma centena de engenheiros dentro da equipe compilador HotSpot da Oracle que discordam sobre a parte "trivial" :-)
Jörg W Mittag
1
@ JörgWMittag, é claro, o HotSpot não é tão simples, faz um pouco de análise estática, está usando os resultados da criação de perfil em tempo de execução, mas ainda assim é muito mais simples que um JIT de rastreamento adequado. E, eu diria, o HotSpot é muito complicado e sua implementação é, para ser educada, um pouco detalhada demais.
SK-logic
1
@Frank Shearar, um JIT ad hoc para uma linguagem dinâmica é tão trivial quanto para uma linguagem de tipo estaticamente (consulte LuaJIT, por exemplo). OTOH, um JIT eficiente é uma coisa totalmente diferente.
SK-logic
21

Há um problema geral com essa questão, pois é absoluta demais. Realmente não faz sentido dizer que "o idioma X é mais rápido que o idioma Y". Uma linguagem de computador em si não é "rápida" ou "lenta" porque é apenas uma maneira de expressar um algoritmo. A pergunta real deve ser algo da ordem de "por que a implementação X1 da linguagem X é mais rápida que a implementação Y1 da linguagem Y para esse domínio de problema específico?"

Algumas diferenças de velocidade certamente cairão fora do próprio idioma, pois certos idiomas são mais fáceis de implementar em determinados domínios do que outros. Mas muito do que torna uma implementação rápida não é a linguagem. Por exemplo, você não pode realmente dizer "Python é mais lento que Java" sem considerar se está falando sobre CPython, IronPython ou PyPy. Isso é particularmente verdadeiro nos idiomas que usam uma VM, pois a velocidade será diretamente afetada pela qualidade da VM.

Além disso, trabalho com um sistema que, por várias razões, não pode usar o JIT em nosso dispositivo com uma VM JavaScript muito popular que normalmente oferece suporte a ela. Isso significa que nosso JavaScript é executado muito, muito mais lentamente do que em um PC com um processador semelhante. Essa alteração, que não está diretamente relacionada à linguagem em si, leva o JavaScript de "algumas vezes mais lento que o C ++" para "ordens de magnitude mais lenta que o C ++" para as tarefas que nos interessam.

Considere também que os idiomas diferem nas características de desempenho de maneiras que não são diretamente comparáveis. Muitos benchmarks apenas traduzem um programa do idioma A para o idioma B e não levam em consideração que os idiomas diferem em quais recursos são rápidos. (Você pode ver isso em qualquer comparação de benchmark razoável, como as que você vincula, pois costumam ter notas como "obrigado por isso por me mostrar como implementá-lo no idioma Foo.)

Por exemplo, tome este código Java:

for(int i=0;i<10;i++) {
    Object o = new Object;
    doSomething(o);
}

Seria tentador "reescrever" isso em C ++ e comparar os tempos de execução:

for(int i=0;i<10;i++) {
    Object *o = new Object;
    doSomething(o);
    delete(o);
}

O problema é que qualquer programador C ++ competente verá imediatamente que, em C ++, essa não é a maneira mais rápida de fazer algo. Você pode facilmente acelerar as coisas alterando-as para serem mais apropriadas ao C ++:

for(int i=0;i<10;i++) {
    Object o;
    doSomething(&o);
}

A questão não é que o C ++ possa ser rápido, mas, em vez de escrever benchmarks para comparar idiomas, é muito, muito difícil. Para fazer isso adequadamente, você precisa ser especialista em ambos os idiomas e escrever do zero nos dois idiomas. Mesmo assim, você pode facilmente encontrar áreas em que um idioma se destaca em uma tarefa específica. Por exemplo, eu posso escrever uma versão do Towers of Hanoi em C ++ que será executada mais rapidamente do que Java em qualquer compilador razoável. Eu posso fazer isso trapaceando essencialmente, usando modelos C ++, avaliados em tempo de compilação (http://forums.devshed.com/c-programming-42/c-towers-of-hanoi-using-templates-424148.html)

A questão não é que eu possa dizer que "C ++ é mais rápido que Java" porque meu programa retornou instantaneamente enquanto a versão Java era executada por minutos (e esperando que ninguém percebesse que meu programa demorou meia hora para ser compilado). O ponto é que, para isso, Em caso estreito, o C ++ é mais rápido. Para outros casos estreitos, pode ser o contrário. Portanto, não é "C ++ é mais rápido", é "C ++ é mais rápido em casos em que você pode avaliar a expressão no tempo de construção usando modelos". Menos satisfatório, mas é verdade.

As diferenças de velocidade nos idiomas são principalmente sobre a implementação. Os idiomas compilados serão mais rápidos que os idiomas interpretados. Compilar no código nativo será mais rápido do que compilar no código de bytes. Isso terá muito mais efeito do que perguntas como se o idioma é estaticamente digitado ou não. E, claro, boas implementações serão mais rápidas que más.

E não esqueça que bons programadores produzirão código mais rápido que programas ruins, geralmente em uma extensão que supera bastante as diferenças de idioma.

Gort the Robot
fonte
6

Tem a ver com a qualidade do compilador, o compilador do java é continuamente otimizado por muito mais tempo, e a otimização é mais importante porque todo o código é compilado para Java. Não tenho certeza do motivo exato do python ser mais rápido que o PHP, mas aposto que é por causa da influência do Google no Python.

Ryathal
fonte
8
Por que isso foi prejudicado? Essa é exatamente a resposta: o desempenho é puramente uma questão de esforço de pesquisa e engenharia e, portanto, em última análise, dinheiro. As empresas que produzem implementações em Java são mais ricas do que as que produzem implementações em Python ou PHP. Isso é tudo.
Jörg W Mittag
1
Além disso, tenho certeza de que as otimizações do CPython não serão aceitas se tornarem o código muito difícil de ler e melhorarem apenas o desempenho por muito pouco.
Cgt
2
+ Jörg W Mittag: Eu discordo. Alguns recursos de linguagem podem ser muito difíceis de implementar com desempenho, portanto, tornam a criação de uma implementação eficiente muito difícil ou quase impossível. Por outro lado, é trivialmente fácil criar uma implementação "eficiente" da linguagem "Assembler".
User281377 4/04
@ammoQ Suspeito que muito disso se refira aos sistemas de tipos e, em particular, à capacidade de saber exatamente qual o tipo que você tem e qual é a semântica exata das operações permitidas. As linguagens dinâmicas ganham flexibilidade por sua natureza, mas dificultam a realização de provas de tipo (e, portanto, a compilação para um código hiper-rápido seguro).
Donal Fellows
1
@DonalFellows Exatamente o meu pensamento. Quanto menos se sabe em tempo de compilação, mais precisa ser descoberto durante o tempo de execução.
User281377
4

Por que o Java é o mais rápido:

O sinalizador + JIT compilado estaticamente + - server estaticamente para recompilar agressivamente o código em execução.

Por que o Python é mais rápido que o PHP:

Python pode ser uma linguagem dinâmica, mas ainda é fortemente tipada. Isso significa que as estruturas que você codifica são capazes de otimização do tempo de execução.

Por que o PHP é péssimo:

É basicamente javascript no servidor (sem suporte a multithreading, totalmente dinâmico, com baixa digitação).

Em essência, quanto mais o compilador souber sobre o seu código, mais ele poderá otimizar. Java é totalmente otimizável antes de ser executado e enquanto estiver em execução. O Python é otimizável enquanto está em execução, e o PHP é, bem, terrível. O Facebook realmente transpila seu PHP para C antes que ele chegue ao servidor.
https://developers.facebook.com/blog/post/2010/02/02/hiphop-for-php--move-fast/

Ajax
fonte
Na verdade, o javascript no servidor é o Node.JS e, pelo que entendi (embora não substancie isso), o mecanismo V8 supera o PHP em geral (embora provavelmente não seja uma tonelada). Além disso, você deve mencionar Python pode ser compilado para nativa (Como ele se comporta em comparação com Java, então?)
Jimmy Hoffa
Eu não usei o python extensivamente o suficiente para ajudá-lo lá, mas posso dizer que o nodejs executando V8 tem suporte para extensões C nativas (apesar de cruzar o limite do JS / C ser supostamente lento), além de poder tirar vantagem do compilador JIT do Google. .. Eu não ficaria surpreso se o nó for mais rápido que o python e o php. Aqui está uma referência (falha como a maioria) blog.famzah.net/2010/07/01/… Observe que o java parecia mais lento que o JS até que um comentarista apontasse nossas falhas na referência ... Então, leve-o com um grão de sal. :)
Ajax
Dito isso, o node e o php também são segmentados individualmente e, a menos que você goste de configurar proxies de cluster (como haproxy), eu não tocaria em nenhum deles em um ambiente de produção sério.
Ajax
1

Os parâmetros de referência são bastante distorcidos em favor de programação matemática pesada.

Não é de surpreender que o Python seja muito bom em matemática complexa se você considerar onde e por que foi escrito pela primeira vez .

Por outro lado, o PHP foi escrito para servir páginas da Web; ele pode fazer outras coisas, mas as páginas da Web são as melhores e estão em pé de igualdade ou melhor que o Java nesta tarefa.

James Anderson
fonte