Por que não devo usar o PyPy sobre o CPython se o PyPy é 6,3 vezes mais rápido?

684

Eu tenho ouvido muito sobre o projeto PyPy . Eles afirmam que é 6,3 vezes mais rápido que o intérprete CPython em seu site .

Sempre que falamos de linguagens dinâmicas como Python, a velocidade é um dos principais problemas. Para resolver isso, eles dizem que o PyPy é 6,3 vezes mais rápido.

A segunda questão é o paralelismo, o infame Global Interpreter Lock (GIL). Para isso, o PyPy diz que pode fornecer o Python sem GIL .

Se o PyPy pode resolver esses grandes desafios, quais são seus pontos fracos que impedem uma adoção mais ampla? Ou seja, o que está impedindo alguém como eu, um típico desenvolvedor de Python, de mudar para o PyPy agora ?

chhantyal
fonte
30
Comentários eliminados, porque a maioria eram coisas que deveriam ser desenvolvidas em respostas (e, em alguns casos, são), ou não deveriam ser ditas. Também editado para abordar algumas das preocupações levantadas em relação à subjetividade desta questão. Tente responder usando fatos e faça backup de afirmações com fontes, se possível!
precisa saber é o seguinte
3
Eu tenho usado muito o Pypy. Tende a funcionar muito bem. No entanto, embora o Pypy seja um pouco mais rápido para muitas cargas de trabalho pesadas da CPU, na verdade é mais lento para as cargas de trabalho pesadas de E / S que eu joguei nele. Por exemplo, escrevi um programa de backup com desduplicação chamado backshift. Para um backup inicial, que processa muitos arquivos, o pypy é ótimo. Mas para backups subseqüentes, que na maioria das vezes estão apenas atualizando registros de data e hora, o CPython é mais rápido.
Dstromberg

Respostas:

657

NOTA: O PyPy está mais maduro e com melhor suporte agora do que em 2013, quando essa pergunta foi feita. Evite tirar conclusões de informações desatualizadas.


  1. PyPy, como outros têm sido rápidos em mencionar, tem o apoio tênue para extensões C . Ele tem suporte, mas geralmente em velocidades mais lentas que o Python e, na melhor das hipóteses, é duvidoso. Portanto, muitos módulos simplesmente requerem CPython. PyPy não suporta numpy PyPy agora suporta numpy . Algumas extensões ainda não são suportadas (Pandas, SciPy etc.), consulte a lista de pacotes suportados antes de fazer a alteração.
  2. O suporte ao Python 3 é experimental no momento. acaba de chegar estável! A partir de 20 de junho de 2014, o PyPy3 2.3.1 - Fulcrum foi lançado !
  3. Às vezes, o PyPy não é realmente mais rápido para "scripts", para os quais muitas pessoas usam o Python. Estes são os programas de execução curta que fazem algo simples e pequeno. Como o PyPy é um compilador JIT, suas principais vantagens vêm de tempos de execução longos e tipos simples (como números). Francamente, as velocidades pré-JIT do PyPy são muito ruins se comparadas ao CPython.
  4. Inércia . Mover-se para o PyPy geralmente requer uma reformulação, o que para algumas pessoas e organizações é simplesmente muito trabalho.

Essas são as principais razões que me afetam, eu diria.

Veedrac
fonte
14
É bom que você mencione a reorganização. Meu host, por exemplo, tem uma escolha entre Python 2.4 e 2.5; e um "grande produtor de software de entretenimento" perto de mim está usando o 2.6, sem planos de atualização em breve. Às vezes, pode ser um esforço grande e caro até descobrir o custo de uma conversão.
Mike Housky
19
Sendo PyPy "tão rápido quanto C", trata-se mais de C genérico do que de bibliotecas C com reconhecimento de cache multithread altamente otimizadas e usadas para números. Para numéricos, o Python é usado apenas para transportar ponteiros para grandes matrizes. Sendo PyPy "tão rápido quanto C" significa "seus ponteiros + metadados são movidos tão rápido quanto C". Não é grande coisa. Então, por que se preocupar com Python? Vá ver as assinaturas de função em cblas e lapacke.
cjordan1
12
@ cjordan1: Eu não entendo o que você está dizendo. As construções numpy de alto nível são extremamente expressivas ( np.sum(M[1:2*n**2:2, :2*n**2] * M[:2*n**2:2, :2*n**2].conjugate(), axis=1)?) No Python e isso o torna muito adequado para a comunidade científica. Além disso, fazer as partes não intensivas em Python e distribuir para C os loops intensivos menores é uma estratégia comum e utilizável.
Veedrac
26
@Veedrac Foi o que eu quis dizer. Como em "Vá ver as assinaturas das funções em cblas e lapacke", porque são tão longas e difíceis de usar que você entenderá instantaneamente por que usamos o Python para contornar os ponteiros e metadados.
cjordan1
5
@ tommy.carstensen Este não é realmente um bom lugar para se aprofundar, mas vou tentar. 1. Isso foi muito mais verdadeiro quando escrevi do que é agora. 2. "Scripts" são frequentemente pesados ​​em IO. O IO do PyPy ainda é frequentemente mais lento que o do CPython - costumava ser significativamente mais lento. 3. O PyPy costumava ser mais lento que o CPython no manuseio de strings - agora é melhor e raramente pior. 4. Muitos "scripts" são apenas códigos de cola - tornar o intérprete mais rápido não melhora os tempos de execução gerais nesse caso. 5. Os tempos de aquecimento do PyPy costumavam ser maiores - scripts de execução curta raramente conseguiam produzir muito código quente.
Veedrac
104

Esse site não afirma que o PyPy é 6,3 vezes mais rápido que o CPython. Citar:

A média geométrica de todos os benchmarks é 0,16 ou 6,3 vezes mais rápida que o CPython

Esta é uma declaração muito diferente da declaração geral que você fez e, quando entender a diferença, entenderá pelo menos um conjunto de razões pelas quais não pode simplesmente dizer "use PyPy". Pode parecer que eu sou muito exigente, mas entender por que essas duas afirmações são totalmente diferentes é vital.

Para dividir isso:

  • A declaração que eles fazem se aplica apenas aos benchmarks que eles usaram. Ele não diz absolutamente nada sobre o seu programa (a menos que ele seja exatamente igual a um de seus benchmarks).

  • A afirmação é sobre uma média de um grupo de benchmarks. Não há alegações de que a execução do PyPy proporcionará uma melhoria de 6,3 vezes, mesmo para os programas que eles testaram.

  • Não há alegação de que PyPy vai mesmo executar todos os programas que CPython é executado em tudo , muito menos rápido.

spookylukey
fonte
15
Obviamente, não há alegação de que o PyPy execute todo o código Python mais rapidamente. Mas se você usar todos os aplicativos Python puros, posso apostar que uma maioria significativa deles será executada muito mais rapidamente (> 3x vezes) no PyPy e no CPython.
Robert Zaremba
18
Nenhum dos seus dois primeiros pontos faz sentido. Como você pode dizer que os benchmarks dizem "absolutamente nada sobre o seu programa". É bastante óbvio que os benchmarks não são um indicador perfeito de todos os aplicativos reais, mas podem definitivamente ser úteis como um indicador. Também não entendo o que você acha enganoso sobre eles, relatando a média de um grupo de benchmarks. Eles afirmam claramente que é uma média. Se um programador não entende o que é uma média, ele tem preocupações muito mais sérias do que o desempenho da linguagem.
Sean Geoffrey Pietz
6
@SeanGeoffreyPietz - eu não estava afirmando que o site do PyPy era enganador - eles apresentaram seus resultados com precisão. Mas a pergunta original os citou erroneamente e estava demonstrando que o autor não entendia a importância da palavra "média". Muitos dos benchmarks individuais não são 6,3 vezes mais rápidos. E se você usar um tipo diferente de média, obterá um valor diferente, portanto "6,3 x mais rápido" não é um resumo adequado de "média geométrica é 6,3 x mais rápido". "O grupo A é Z vezes mais rápido que o grupo B" é muito vago para ser significativo.
Spookylukey
6
-1: @spookylukey Você parece sugerir que o conjunto de benchmarks é tendencioso sem fornecer evidências para apoiar a reivindicação. As críticas devem sempre ser apoiadas com evidências!
Evgeni Sergeev
5
@ EvgeniSergeev - não, estou implicando que todos os benchmarks são tendenciosos! Não necessariamente deliberadamente, é claro. O espaço de possíveis programas úteis é infinito e incrivelmente variado, e um conjunto de benchmarks apenas mede o desempenho desses benchmarks. Perguntando "quanto mais rápido é o PyPy do que o CPython?" é como perguntar "quanto mais rápido Fred do que Joe?", que é o que o OP parece querer saber.
Spookylukey
74

Como o pypy não é 100% compatível, leva 8 GB de RAM para compilar, é um alvo em movimento e altamente experimental, onde o cpython é estável, o alvo padrão para os construtores de módulos por 2 décadas (incluindo extensões c que não funcionam no pypy ) e já amplamente implantado.

O Pypy provavelmente nunca será a implementação de referência, mas é uma boa ferramenta para ter.

Tritium21
fonte
2
De acordo com pypy.org/download.html , o PyPy precisa de 4 GB de RAM para compilar (em um sistema de 64 bits), não 8. E há uma opção nessa página para fazê-lo com menos de 3 GB, se necessário.
Knite
4
@ knite 1: que é novo a partir de 2015, a documentação tem historicamente 8 GB. 2: na prática em 2015, você ainda precisa de pelo menos 8, com 6-7 de graça.
Tritium21
4
O requisito de memória para compilar não é tão relevante se você usar uma compilação ou distribuição . Quanto a "alvo em movimento e altamente experimental", você pode dar alguns exemplos de coisas que quebram? Novamente, se as pessoas estiverem usando versões de lançamento em vez de versões noturnas ou origem, elas não têm uma expectativa razoável de funcionalidade?
SMCI
@smci Esta é uma pergunta antiga baseada em dados antigos, com respostas antigas. Considere esta pergunta e todas as respostas como históricas para o estado de pypy há 4 anos.
precisa saber é o seguinte
1
@ Tritium21: Estou interessado apenas na resposta atual. O que é isso? Você pode editar sua resposta para dizer "A partir de 2013, a comparação entre o pypy e a versão 2.x do Python era ..." Além disso, se a declaração "média geométrica de 6.3x" na pergunta estiver desatualizada ( como de 4/2017 eles reivindicam 7,5x, mas mesmo assim depende dos benchmarks ... ), então isso também precisa ser editado (números de versão, dados mais recentes etc.) Acho que o conjunto de benchmarks não é muito relevante, dificilmente alguém executaria raytracing em uma linguagem de script em uma CPU atualmente. Eu encontrei pybenchmarks.org
smci
36

A segunda pergunta é mais fácil de responder: você basicamente pode usar o PyPy como um substituto, se todo o seu código for puro Python. No entanto, muitas bibliotecas amplamente usadas (incluindo algumas da biblioteca padrão) são escritas em C e compiladas como extensões Python. Alguns deles podem ser feitos para trabalhar com o PyPy, outros não. O PyPy fornece a mesma ferramenta "voltada para a frente" que o Python --- isto é, é Python --- mas suas entranhas são diferentes, portanto, as ferramentas que fazem interface com essas entranhas não funcionam.

Quanto à primeira pergunta, imagino que seja uma espécie de Catch-22 com a primeira: o PyPy está evoluindo rapidamente em um esforço para melhorar a velocidade e aprimorar a interoperabilidade com outro código. Isso tornou mais experimental do que oficial.

Eu acho que é possível que, se o PyPy entrar em um estado estável, ele possa começar a ser mais amplamente usado. Eu também acho que seria ótimo para Python se afastar de seus fundamentos em C. Mas isso não vai acontecer por um tempo. O PyPy ainda não atingiu a massa crítica, onde é quase útil o suficiente para fazer tudo o que você deseja, o que motivaria as pessoas a preencher as lacunas.

BrenBarn
fonte
17
Não acho que C seja uma linguagem que vá a lugar algum tão cedo (eu estaria disposto a dizer que não desaparecerá em nossa vida). até que exista outro idioma que seja executado em qualquer lugar, teremos C. (observe que a JVM é escrita em C. Até o java, o idioma que "roda em todos os lugares" precisa de C por toda a sua integridade.) Caso contrário, concordo com este post dos seus pontos.
precisa saber é o seguinte
7
@ Tritium21: Sim, estou apenas editorializando lá. Eu estou bem com o C existente, mas acho que a dependência do Python em C é extremamente prejudicial, e o PyPy é um ótimo exemplo do porquê: agora temos a chance de obter o Python mais rápido, mas somos enganados por anos confiando no C Seria muito melhor para Python se sustentar sozinho. É ainda certo se o próprio Python é escrito em C, mas o problema é a existência de um mecanismo de extensão que incentiva as pessoas a estender Python de maneiras que dependem C.
BrenBarn
4
uma espada de ponta dupla nisso - parte do que tornou o python tão popular é sua capacidade de estender outros aplicativos e ser estendida por outros aplicativos. Se você tirar isso, não acho que estaríamos falando sobre python.
precisa saber é o seguinte
10
@BrenBarn É tolice afirmar que a dependência do Python em C é prejudicial. Sem a C-API do Python, a maioria das bibliotecas realmente poderosas e a grande interoperabilidade que o Python obteve na adolescência formativa (final dos anos 90), incluindo todo o ecossistema numérico / científico e as interfaces GUI, não teriam sido possíveis. Olhe ao redor para ter uma perspectiva de todo o universo de usos do Python, antes de fazer essas declarações gerais.
Peter Wang
4
@ PeterWang Todas essas bibliotecas podem ser escritas em Python, mas não seriam tão rápidas quanto são. O que o BrenBarn está dizendo é que agora temos a chance de tornar o python rápido o suficiente para que essas bibliotecas possam ser escritas em python, mas estamos nos recusando a aproveitar essa chance, porque isso significa perder a capacidade de usar as bibliotecas C. Eu acredito que é o que ele quis dizer com prejudicial, não que a existência de bibliotecas C é uma coisa ruim, mas que a única maneira de fazer bibliotecas rápidas está usando C.
vikki
14

Fiz uma pequena referência sobre esse tópico. Enquanto muitos dos outros pôsteres fizeram bons comentários sobre compatibilidade, minha experiência foi que o PyPy não é muito mais rápido apenas para mover os bits. Para muitos usos do Python, ele realmente existe apenas para converter bits entre dois ou mais serviços. Por exemplo, não há muitos aplicativos da web executando análises intensivas da CPU de conjuntos de dados. Em vez disso, eles pegam alguns bytes de um cliente, os armazenam em algum tipo de banco de dados e depois os devolvem para outros clientes. Às vezes, o formato dos dados é alterado.

Os desenvolvedores do BDFL e do CPython são um grupo de pessoas notavelmente inteligente e conseguiram ajudar o CPython a ter um desempenho excelente nesse cenário. Aqui está um plug-in de vergonha do blog: http://www.hydrogen18.com/blog/unpickling-buffers.html . Estou usando o Stackless, que é derivado do CPython e mantém a interface completa do módulo C. Não encontrei nenhuma vantagem em usar o PyPy nesse caso.

Eric Urban
fonte
1
O PyPy possui muitos benchmarks cuidadosamente executados (ao contrário do CPython, infelizmente, que atualmente não possui um conjunto de benchmarks voltado para o usuário). Obviamente, para o tráfego de rede, o PyPy não pode magicamente fazer nada mais rápido.
Julian
1
Julian, vale a pena notar que o pessoal do PyPy tem se concentrado muito em melhorar os tempos de execução desse conjunto de benchmarks há anos. Até certo ponto, parece que eles estão "adaptando demais" suas otimizações a esse conjunto de benchmarks e, na minha experiência, além de cálculos puramente numéricos (que são melhores em Fortran ou C99 de qualquer maneira), nunca consegui que o PyPy fosse mais do que ~ 2X mais rápido que o CPython.
Alex Rubinsteyn
9
@AlexRubinsteyn Mas a visão dos que trabalham no PyPy sempre foi que, se você encontra um caso em que o PyPy é mais lento que o CPython e pode transformá-lo em uma referência razoável, há uma boa chance de ser adicionado ao conjunto.
gsnedders
1
Eu verifiquei seu blog. Nos seus resultados, o par de python simples (pickle, StringIO) mostra que o pypy é ~ 6,8x mais rápido que o cpython. Eu acho que esse é um resultado útil. Na sua conclusão, você aponta (corretamente) que o código pypy (que é simples em python!) É mais lento que o código C (cPickle, cStringIO), não o código cpython.
Caleb Hattingh
1
@gsnedders Eu ofereci um benchmark baseado no rinohtype em várias ocasiões . Eles ainda não o adicionaram à suíte.
Brecht Machiels
12

P: Se o PyPy pode resolver esses grandes desafios (velocidade, consumo de memória, paralelismo) em comparação com o CPython, quais são seus pontos fracos que impedem uma adoção mais ampla?

R: Primeiro, há poucas evidências de que a equipe do PyPy possa resolver o problema de velocidade em geral . Evidências de longo prazo mostram que o PyPy executa certos códigos Python mais lentamente que o CPython e essa desvantagem parece estar profundamente enraizada no PyPy.

Em segundo lugar, a versão atual do PyPy consome muito mais memória que o CPython em um conjunto bastante grande de casos. Portanto, o PyPy ainda não resolveu o problema de consumo de memória.

Se o PyPy resolve os grandes desafios mencionados e, em geral, será mais rápido, com menos memória e mais amigável ao paralelismo do que o CPython, é uma questão em aberto que não pode ser resolvida a curto prazo. Algumas pessoas estão apostando que o PyPy nunca poderá oferecer uma solução geral que permita dominar o CPython 2.7 e 3.3 em todos os casos.

Se o PyPy conseguir ser melhor que o CPython em geral, o que é questionável, a principal fraqueza que afeta sua adoção mais ampla será a compatibilidade com o CPython. Também existem questões como o fato de o CPython ser executado em uma ampla variedade de CPUs e sistemas operacionais, mas essas questões são muito menos importantes em comparação com o desempenho do PyPy e os objetivos de compatibilidade com o CPython.


P: Por que não posso substituir o CPython pelo PyPy agora?

R: O PyPy não é 100% compatível com o CPython, porque não está simulando o CPython. Alguns programas ainda podem depender dos recursos exclusivos do CPython ausentes no PyPy, como ligações C, implementações C de objetos e métodos Python ou a natureza incremental do coletor de lixo do CPython.


fonte
Esta resposta não cita nenhum parâmetro de referência ou fornece referências.
QWR
7

O CPython possui contagem de referência e coleta de lixo, o PyPy possui apenas coleta de lixo.

Portanto, os objetos tendem a ser excluídos anteriormente e __del__são chamados de uma maneira mais previsível no CPython. Alguns softwares dependem desse comportamento e, portanto, não estão prontos para migrar para o PyPy.

Alguns outros softwares funcionam com ambos, mas usam menos memória com o CPython, porque objetos não utilizados são liberados anteriormente. (Não tenho medidas para indicar o quão significativo isso é e que outros detalhes de implementação afetam o uso da memória.)

pts
fonte
17
Deve-se enfatizar que confiar em __del__ser chamado cedo ou totalmente está errado, mesmo no CPython. Como você diz, geralmente funciona e algumas pessoas entendem isso como garantido. Se alguma coisa que referencie o objeto for capturada em um ciclo de referência (o que é bastante fácil - você sabia que a inspeção da exceção atual de uma certa maneira não artificial cria um ciclo de referência?) A finalização é adiada indefinidamente, até o próximo ciclo GC (que pode nunca ser ). Se o próprio objeto fizer parte de um ciclo de referência, __del__ele não será chamado de forma alguma (antes do Python 3.4).
3
A sobrecarga por objeto é maior no CPython, o que é muito importante quando você começa a criar muitos objetos. Acredito que o PyPy faz o equivalente a slots por padrão, por um lado.
4

Para muitos projetos, há realmente 0% de diferença entre os diferentes pitães em termos de velocidade. São aqueles que são dominados pelo tempo de engenharia e onde todos os pitães têm a mesma quantidade de suporte de biblioteca.

Stephan Eggermont
fonte
1
Se o seu projeto é simples assim, obviamente não importa, mas o mesmo poderia ser dito de qualquer implementação de qualquer linguagem: se tudo o que você faz é agregar as funções de outras bibliotecas por meio de ABIs com desempenho relativamente alto, tudo isso é irrelevante.
1
Não tem nada a ver com simples. No tempo de engenharia, o ciclo de feedback é importante. Às vezes, muito mais importante que o tempo de execução.
21413 Stephan Stephangerger
1
Bem, você está falando muito vagamente (tempo de engenharia sem referência ao que está sendo projetado, quais são as restrições etc.); ciclo de feedback sem referência ao que está sendo enviado a quem, etc.), então vou sair dessa conversa em vez de trocar referências enigmáticas.
Nada vago aqui. Dê uma olhada no loop OODA, ou PDCA.
precisa saber é o seguinte
3
@user Bem, qualquer projeto executado uma vez que leve um mês para escrever e um minuto para executar terá uma velocidade geral de 0,0% (1 mês + 1 minuto vs 1 mês) ao usar o PyPy, mesmo que o PyPy fosse mil vezes mais rápido. Stephan não estava afirmando que todos os projetos teriam uma velocidade de 0%.
gmatht
4

Para simplificar: o PyPy fornece a velocidade que falta ao CPython, mas sacrifica sua compatibilidade. A maioria das pessoas, no entanto, escolhe o Python por sua flexibilidade e por seu recurso "incluído na bateria" (alta compatibilidade), não por sua velocidade (ainda é o preferido).

Yishen Chen
fonte
16
"bateria incluída" significa uma grande biblioteca padrão , AFAIK
tshepang 5/05
4

Encontrei exemplos em que o PyPy é mais lento que o Python. Mas: apenas no Windows.

C:\Users\User>python -m timeit -n10 -s"from sympy import isprime" "isprime(2**521-1);isprime(2**1279-1)"
10 loops, best of 3: 294 msec per loop

C:\Users\User>pypy -m timeit -n10 -s"from sympy import isprime" "isprime(2**521-1);isprime(2**1279-1)"
10 loops, best of 3: 1.33 sec per loop

Então, se você pensa em PyPy, esqueça o Windows. No Linux, você pode obter incríveis acelerações. Exemplo (liste todos os números primos entre 1 e 1.000.000):

from sympy import sieve
primes = list(sieve.primerange(1, 10**6))

Isso é executado 10 (!) Vezes mais rápido no PyPy do que no Python. Mas não nas janelas. Lá é apenas 3x mais rápido.

lifolofi
fonte
Interessante! Mais algumas comparações e números teriam sido ótimos.
ben26941
1

O PyPy tem suporte ao Python 3 há algum tempo, mas, de acordo com este post do HackerNoon por Anthony Shaw de 2 de abril de 2018 , o PyPy3 ainda é várias vezes mais lento que o PyPy (Python 2).

Para muitos cálculos científicos, particularmente cálculos matriciais, o numpy é uma escolha melhor (consulte Perguntas frequentes: devo instalar o numpy ou o numpypy? ).

O Pypy não suporta gmpy2. Em vez disso, você pode usar o gmpy_cffi, embora eu não tenha testado sua velocidade e o projeto tenha sido lançado em 2014.

Para problemas do Project Euler, faço uso frequente do PyPy, e para cálculos numéricos simples muitas vezes from __future__ import divisioné suficiente para meus propósitos, mas o suporte ao Python 3 ainda está sendo trabalhado a partir de 2018, com sua melhor aposta no Linux de 64 bits. O Windows PyPy3.5 v6.0, o mais recente em dezembro de 2018, está na versão beta.

qwr
fonte
0

Versões suportadas do Python

Para citar o Zen do Python :

Legibilidade conta.

Por exemplo, o Python 3.7 introduziu classes de dados e o Python 3.8 introduziu fstring = .

Pode haver outros recursos no Python 3.7 e Python 3.8 que são mais importantes para você. O ponto é que o PyPy não suporta o Python 3.7 ou o Python 3.8 no momento.

Martin Thoma
fonte