¿Por qué no debería usar PyPy sobre CPython si PyPy es 6.3 veces más rápido?

685

He estado escuchando mucho sobre el proyecto PyPy . Afirman que es 6.3 veces más rápido que el CPython intérprete de en su sitio .

Siempre que hablamos de lenguajes dinámicos como Python, la velocidad es uno de los principales problemas. Para resolver esto, dicen que PyPy es 6.3 veces más rápido.

El segundo problema es el paralelismo, el infame Global Interpreter Lock (GIL). Para esto, PyPy dice que puede dar Python sin GIL .

Si PyPy puede resolver estos grandes desafíos, ¿cuáles son sus debilidades que impiden una adopción más amplia? Es decir, ¿qué impide que alguien como yo, un desarrollador típico de Python, cambie a PyPy en este momento ?

chhantyal
fuente
30
Comentarios purgados porque la mayoría eran cosas que debían desarrollarse en las respuestas (y en algunos casos lo son), o no deberían decirse en absoluto. También editado para abordar un par de inquietudes planteadas con respecto a la subjetividad de esta pregunta. ¡Por favor, intente responder con hechos y haga una copia de seguridad de las afirmaciones con fuentes si es posible!
Shog9
3
He estado usando mucho Pypy. Tiende a funcionar muy bien. Sin embargo, si bien Pypy es bastante más rápido para muchas cargas de trabajo pesadas de CPU, en realidad es más lento para las cargas de trabajo pesadas de E / S que le he lanzado. Por ejemplo, escribí un programa de copia de seguridad de deduplicación llamado retroceso. Para una copia de seguridad inicial, que hace muchos fragmentos de archivos, pypy es genial. Pero para las copias de seguridad posteriores, que en su mayoría solo actualizan las marcas de tiempo, CPython es más rápido.
dstromberg

Respuestas:

657

NOTA: PyPy es más maduro y mejor soportado ahora que en 2013, cuando se hizo esta pregunta. Evite sacar conclusiones de información desactualizada.


  1. PyPy, como otros se han apresurado a hablar, tiene soporte para extensiones C tenue . Se cuenta con el apoyo, pero por lo general a una velocidad más lenta de lo Python y es dudoso en el mejor. Por lo tanto, muchos módulos simplemente requieren CPython. PyPy no admite numpy. PyPy ahora admite numpy . Algunas extensiones aún no son compatibles (Pandas, SciPy, etc.), eche un vistazo a la lista de paquetes compatibles antes de realizar el cambio.
  2. El soporte de Python 3 es experimental en este momento. acaba de llegar estable! A partir del 20 de junio de 2014, PyPy3 2.3.1 - ¡Fulcrum está disponible !
  3. PyPy a veces no es realmente más rápido para "scripts", para lo cual mucha gente usa Python. Estos son los programas de ejecución corta que hacen algo simple y pequeño. Debido a que PyPy es un compilador JIT, sus principales ventajas provienen de tiempos de ejecución largos y tipos simples (como números). Francamente, las velocidades anteriores a JIT de PyPy son bastante malas en comparación con CPython.
  4. La inercia . Pasar a PyPy a menudo requiere una actualización, lo que para algunas personas y organizaciones es simplemente demasiado trabajo.

Esas son las principales razones que me afectan, diría.

Veedrac
fuente
14
Es bueno que menciones reorganización. Mi proveedor de alojamiento web, por ejemplo, puede elegir entre Python 2.4 y 2.5; y un "gran productor de software de entretenimiento" cerca de mí está usando 2.6 sin planes para actualizar pronto. A veces puede ser un esfuerzo importante y costoso incluso descubrir el costo de una conversión.
Mike Housky
19
PyPy es "tan rápido como C" tiene más que ver con C genérico que con las bibliotecas de C multihilo altamente optimizadas y con reconocimiento de caché utilizadas para los números. Para los números, Python solo se usa para transportar punteros a grandes matrices. Entonces, PyPy es "tan rápido como C" significa "sus punteros + metadatos se mueven tan rápido como C". No es un gran trato. Entonces, ¿por qué molestarse con Python? Ve a ver las firmas de funciones en cblas y lapacke.
cjordan1
12
@ cjordan1: No entiendo lo que estás diciendo. Las construcciones numpy de alto nivel son extremadamente expresivas ( np.sum(M[1:2*n**2:2, :2*n**2] * M[:2*n**2:2, :2*n**2].conjugate(), axis=1)?) En Python y eso hace que Python sea muy adecuado para la comunidad científica. Además, hacer las partes no intensivas en Python y desplazarse a C para los bucles intensivos más pequeños es una estrategia común y utilizable.
Veedrac
26
@Veedrac A eso me refería. Como en "Ir, mira las firmas de funciones en cblas y lapacke" porque son tan largas y difíciles de usar que comprenderás instantáneamente por qué usamos Python para navegar alrededor de los punteros y metadatos.
cjordan1
55
@ tommy.carstensen Este no es realmente un buen lugar para profundizar, pero lo intentaré. 1. Esto fue mucho más cierto cuando lo escribí de lo que es ahora. 2. Los "guiones" son a menudo muy pesados. El IO de PyPy es a menudo más lento que el de CPython: solía ser significativamente más lento. 3. PyPy solía ser más lento que CPython en el manejo de cadenas; ahora a menudo es mejor y rara vez peor. 4. Muchos "scripts" son solo código de pegamento; hacer que el intérprete sea más rápido no mejorará los tiempos de ejecución generales en ese caso. 5. Los tiempos de calentamiento de PyPy solían ser mayores: los scripts de ejecución corta rara vez lograban producir mucho código dinámico.
Veedrac
104

Ese sitio no afirma que PyPy sea 6.3 veces más rápido que CPython. Citar:

El promedio geométrico de todos los puntos de referencia es 0.16 o 6.3 veces más rápido que CPython

Esta es una muy declaración diferente a la declaración general que hizo, y cuando comprenda la diferencia, comprenderá al menos un conjunto de razones por las que no puede simplemente decir "use PyPy". Puede sonar como que estoy buscando cosas, pero entender por qué estas dos afirmaciones son totalmente diferentes es vital.

Para desglosar eso:

  • La declaración que hacen solo se aplica a los puntos de referencia que han utilizado. No dice absolutamente nada acerca de su programa (a menos que su programa sea exactamente el mismo que uno de sus puntos de referencia).

  • La declaración es sobre un promedio de un grupo de puntos de referencia. No se afirma que ejecutar PyPy proporcionará una mejora de 6.3 veces incluso para los programas que han probado.

  • No hay ninguna afirmación de que PyPy incluso ejecutar todos los programas que ejecuta CPython en absoluto , y mucho menos rápido.

Spookylukey
fuente
15
Por supuesto, no se afirma que PyPy ejecutará todo el código Python más rápido. Pero si toma todas las aplicaciones Python puras, puedo apostar que la mayoría significativa de ellas se ejecutará mucho más rápido (> 3 veces) en PyPy que en CPython.
Robert Zaremba
18
Ninguno de los dos primeros puntos tiene sentido. ¿Cómo puede decir que los puntos de referencia dicen "absolutamente nada acerca de su programa"? Es bastante obvio que los puntos de referencia no son un indicador perfecto de todas las aplicaciones reales, pero definitivamente pueden ser útiles como indicador. Además, no entiendo lo que encuentras engañoso acerca de que informan el promedio de un grupo de puntos de referencia. Afirman bastante claramente que es un promedio. Si un programador no entiende qué es un promedio, entonces tiene preocupaciones mucho más serias que el rendimiento del lenguaje.
Sean Geoffrey Pietz el
66
@SeanGeoffreyPietz: no estaba afirmando que el sitio de PyPy fuera engañoso, han presentado sus resultados con precisión. Pero la pregunta original los citó erróneamente y demostraba que el autor no entendía la importancia de la palabra "promedio". Muchos de los puntos de referencia individuales no son 6.3 veces más rápidos. Y si usa un tipo diferente de promedio, obtiene un valor diferente, por lo que "6.3 x más rápido" no es un resumen adecuado de "el promedio geométrico es 6.3 x más rápido". "El grupo A es Z veces más rápido que el grupo B" es demasiado vago para ser significativo.
spookylukey
66
-1: @spookylukey Parece sugerir que el conjunto de pruebas de referencia está sesgado sin proporcionar evidencia para respaldar el reclamo. ¡Las críticas siempre deben estar respaldadas con evidencia!
Evgeni Sergeev
55
@EvgeniSergeev: ¡no, estoy insinuando que todos los puntos de referencia están sesgados! No necesariamente deliberadamente, por supuesto. El espacio de posibles programas útiles es infinito e increíblemente variado, y un conjunto de puntos de referencia solo mide el rendimiento en esos puntos de referencia. Preguntando "¿cuánto más rápido es PyPy que CPython?" es como preguntar "¿cuánto más rápido si Fred que Joe?", que es lo que el OP parece querer saber.
spookylukey
74

Debido a que pypy no es 100% compatible, toma 8 gigas de ram para compilar, es un objetivo móvil y altamente experimental, donde cpython es estable, el objetivo predeterminado para los constructores de módulos durante 2 décadas (incluidas las extensiones c que no funcionan en pypy) ), y ya ampliamente implementado.

Pypy probablemente nunca será la implementación de referencia, pero es una buena herramienta para tener.

Tritio21
fuente
2
De acuerdo con pypy.org/download.html , PyPy necesita 4 GB de RAM para compilar (en un sistema de 64 bits), no 8. Y hay una opción en esa página para hacerlo por debajo de 3 GB si es necesario.
Knite
44
@knite 1: eso es nuevo a partir de 2015, la documentación ha leído históricamente 8 GB. 2: en la práctica en 2015 todavía necesita al menos 8, con 6-7 gratis.
Tritium21
44
El requisito de memoria para compilar no es tan relevante si utiliza una compilación o distribución . En cuanto a "objetivo móvil y altamente experimental", ¿puede dar un par de ejemplos de cosas que se rompen? Nuevamente, si las personas usan versiones de lanzamiento en lugar de versiones nocturnas o fuente, ¿no tienen una expectativa razonable de funcionalidad?
smci
@smci Esta es una pregunta antigua basada en datos antiguos, con respuestas antiguas. Considere esta pregunta y cada respuesta como históricas para el estado de pypy hace 4 años.
Tritium21
1
@ Tritium21: solo me interesa la respuesta actual. ¿Qué es? Es posible que desee editar su respuesta para decir "A partir de 2013, la comparación de pypy con la versión 2.x de Python era ..." También si el reclamo de "promedio geométrico 6.3x" en la pregunta no está actualizado ( como de 4/2017 reclaman 7.5x, pero incluso entonces depende de los puntos de referencia ... ), entonces eso también necesita edición (números de versión, datos más recientes, etc.) Creo que el conjunto de puntos de referencia no es muy relevante, casi nadie correría raytracing en un lenguaje de script en una CPU en estos días. Encontré pybenchmarks.org
smci
37

La segunda pregunta es más fácil de responder: básicamente puedes usar PyPy como reemplazo directo si todo su código es Python puro. Sin embargo, muchas bibliotecas ampliamente utilizadas (incluidas algunas de la biblioteca estándar) están escritas en C y compiladas como extensiones de Python. Algunos de estos pueden hacerse funcionar con PyPy, otros no. PyPy proporciona la misma herramienta "orientada hacia adelante" que Python, es decir, es Python, pero sus entrañas son diferentes, por lo que las herramientas que interactúan con esas entrañas no funcionarán.

En cuanto a la primera pregunta, me imagino que es una especie de Catch-22 con la primera: PyPy ha evolucionado rápidamente en un esfuerzo por mejorar la velocidad y mejorar la interoperabilidad con otro código. Esto lo ha hecho más experimental que oficial.

Creo que es posible que si PyPy entra en un estado estable, puede comenzar a ser más utilizado. También creo que sería genial para Python alejarse de sus cimientos. Pero no sucederá por un tiempo. PyPy aún no ha alcanzado la masa crítica donde es casi lo suficientemente útil por sí solo para hacer todo lo que desee, lo que motivaría a las personas a llenar los vacíos.

BrenBarn
fuente
17
No creo que C sea un lenguaje que irá a algún lado pronto (estaría dispuesto a decir que no desaparecerá en nuestra vida). hasta que haya otro lenguaje que se ejecute en cualquier lugar, tendremos C. (tenga en cuenta que la JVM está escrita en C. Incluso Java, el lenguaje que "se ejecuta en todas partes" necesita C para su presencia). De lo contrario, estoy de acuerdo con esta publicación en la mayoría de sus puntos.
Tritium21
77
@ Tritium21: Sí, solo estoy editorializando allí. Estoy bien con la existencia de C, pero creo que la dependencia de Python en C es muy perjudicial, y PyPy es un gran ejemplo de por qué: ahora tenemos la oportunidad de obtener Python más rápido, pero nos hemos tropezado por años de depender de C Sería mucho mejor para Python pararse por sí mismo. Incluso está bien si Python está escrito en C, pero el problema es la existencia de un mecanismo de extensión que alienta a las personas a extender Python de manera que dependa de C.
BrenBarn
44
espada de doble filo en eso: parte de lo que hizo que Python fuera tan popular es su capacidad de extender otras aplicaciones y ser extendido por otras aplicaciones. Si quitas eso, no creo que estemos hablando de Python.
Tritium21
10
@BrenBarn Es una locura afirmar que la dependencia de Python de C es perjudicial. Sin la C-API de Python, la mayoría de las bibliotecas realmente poderosas y la gran interoperabilidad que Python obtuvo en su adolescencia formativa (finales de los 90), incluido todo el ecosistema numérico / científico y las interfaces GUI, no hubieran sido posibles. Mire a su alrededor para obtener una perspectiva sobre todo el universo de usos de Python, antes de hacer tales declaraciones generales.
Peter Wang
44
@PeterWang Todas esas bibliotecas se pueden escribir en Python, sin embargo, no serían tan rápidas como lo son. Lo que dice BrenBarn es que ahora tenemos la oportunidad de hacer que Python sea lo suficientemente rápido para que esas librerías puedan escribirse en Python, pero nos negamos a aprovechar esa oportunidad, porque aprovecharla significa perder la capacidad de usar las bibliotecas C. Creo que eso es lo que quiso decir con perjudicial, no que la existencia de bibliotecas C sea algo malo, sino que la única forma de crear bibliotecas rápidas es usar C.
vikki
14

Hice un pequeño punto de referencia sobre este tema. Si bien muchos de los otros carteles han hecho buenos comentarios sobre la compatibilidad, mi experiencia ha sido que PyPy no es mucho más rápido para moverse por bits. Para muchos usos de Python, realmente solo existe para traducir bits entre dos o más servicios. Por ejemplo, no muchas aplicaciones web realizan análisis intensivos de CPU de conjuntos de datos. En cambio, toman algunos bytes de un cliente, los almacenan en algún tipo de base de datos y luego los devuelven a otros clientes. A veces se cambia el formato de los datos.

Los desarrolladores de BDFL y CPython son un grupo de personas notablemente inteligente y han logrado ayudar a CPython a desempeñarse de manera excelente en tal escenario. Aquí hay un complemento de blog descarado: http://www.hydrogen18.com/blog/unpickling-buffers.html . Estoy usando Stackless, que se deriva de CPython y conserva la interfaz completa del módulo C. No encontré ninguna ventaja al usar PyPy en ese caso.

Eric Urban
fuente
1
PyPy tiene muchos puntos de referencia cuidadosamente ejecutados (a diferencia de CPython desafortunadamente, que en este momento no tiene realmente un conjunto de puntos de referencia orientado al usuario). Por supuesto, para el tráfico de red, PyPy no puede hacer nada mágicamente más rápido.
Juliano
1
Julian, vale la pena señalar que la gente de PyPy se ha centrado mucho esfuerzo en mejorar los tiempos de ejecución de esa suite de referencia en particular durante años. Hasta cierto punto, parece que están "ajustando demasiado" sus optimizaciones a este conjunto de puntos de referencia y, en mi experiencia, aparte de los cálculos puramente numéricos (que de todos modos están mejor en Fortran o C99), nunca he conseguido que PyPy sea más ~ 2 veces más rápido que CPython.
Alex Rubinsteyn
99
@AlexRubinsteyn Pero la opinión de aquellos que trabajan en PyPy siempre ha sido que si encuentras un caso en el que PyPy es más lento que CPython, y puedes convertirlo en un punto de referencia razonable, tiene muchas posibilidades de ser agregado a la suite.
gsnedders
1
Revisé tu blog. En sus resultados, el par de python (pickle, StringIO) muestra que pypy es ~ 6.8x más rápido que cpython. Creo que este es un resultado útil. En su conclusión, señala (correctamente) que el código pypy (¡que es python simple!) Es más lento que el código C (cPickle, cStringIO), no el código cpython.
Caleb Hattingh
1
@gsnedders He ofrecido un punto de referencia basado en rinohtype en múltiples ocasiones . Todavía no lo han agregado a la suite.
Brecht Machiels
12

P: Si PyPy puede resolver estos grandes desafíos (velocidad, consumo de memoria, paralelismo) en comparación con CPython, ¿cuáles son sus debilidades que impiden una adopción más amplia?

R: Primero, hay poca evidencia de que el equipo de PyPy pueda resolver el problema de la velocidad en general . La evidencia a largo plazo muestra que PyPy ejecuta ciertos códigos de Python más lentamente que CPython y este inconveniente parece estar muy arraigado en PyPy.

En segundo lugar, la versión actual de PyPy consume mucha más memoria que CPython en un conjunto bastante grande de casos. Así que PyPy todavía no resolvió el problema del consumo de memoria.

Si PyPy resuelve los grandes desafíos mencionados y, en general, será más rápido, menos hambriento de memoria y más amigable al paralelismo que CPython es una pregunta abierta que no se puede resolver a corto plazo. Algunas personas apuestan a que PyPy nunca podrá ofrecer una solución general que le permita dominar CPython 2.7 y 3.3 en todos los casos.

Si PyPy logra ser mejor que CPython en general, lo cual es cuestionable, la principal debilidad que afecta su adopción más amplia será su compatibilidad con CPython. También existen problemas como el hecho de que CPython se ejecuta en una gama más amplia de CPU y sistemas operativos, pero estos problemas son mucho menos importantes en comparación con el rendimiento de PyPy y los objetivos de compatibilidad de CPython.


P: ¿Por qué no puedo dejar de reemplazar CPython con PyPy ahora?

R: PyPy no es 100% compatible con CPython porque no simula CPython debajo del capó. Algunos programas aún pueden depender de las características únicas de CPython que están ausentes en PyPy, tales como enlaces C, implementaciones C de objetos y métodos de Python, o la naturaleza incremental del recolector de basura de CPython.


fuente
Esta respuesta no cita ningún punto de referencia ni proporciona referencias.
qwr
7

CPython tiene conteo de referencias y recolección de basura, PyPy solo tiene recolección de basura.

Por lo tanto, los objetos tienden a eliminarse antes y __del__se llama de una manera más predecible en CPython. Algunos softwares dependen de este comportamiento, por lo que no están listos para migrar a PyPy.

Otro software funciona con ambos, pero usa menos memoria con CPython, porque los objetos no utilizados se liberan antes. (No tengo ninguna medida para indicar qué tan importante es esto y qué otros detalles de implementación afectan el uso de la memoria).

pts
fuente
17
Debe enfatizarse que confiar en __del__ser llamado temprano o en absoluto es incorrecto incluso en CPython. Como lo expresas, generalmente funciona y algunas personas lo entienden como garantía. Si algo que hace referencia al objeto está atrapado en un ciclo de referencia (lo cual es bastante fácil, ¿sabía que inspeccionar la excepción actual de una manera no artificial crea un ciclo de referencia?) La finalización se retrasa indefinidamente, hasta el siguiente ciclo GC (que puede ser nunca ). Si el objeto es parte de un ciclo de referencia, __del__no se llamará en absoluto (antes de Python 3.4).
3
La sobrecarga por objeto es más alta en CPython, lo que importa MUCHO una vez que comienza a crear muchos objetos. Creo que PyPy hace el equivalente de las ranuras de forma predeterminada, por un lado.
4

Para muchos proyectos, en realidad hay una diferencia del 0% entre las diferentes pitones en términos de velocidad. Esos son aquellos que están dominados por el tiempo de ingeniería y donde todas las pitones tienen la misma cantidad de soporte de biblioteca.

Stephan Eggermont
fuente
1
Si su proyecto es así de simple, entonces obviamente no importa, pero podría decirse lo mismo de cualquier implementación de cualquier lenguaje: si todo lo que hace es agregar las funciones de otras bibliotecas a través de ABI relativamente efectivas, entonces todo es irrelevante.
1
No tiene nada que ver con simple. En tiempo de ingeniería, el ciclo de retroalimentación es importante. A veces es mucho más importante que el tiempo de ejecución.
Stephan Eggermont
1
Bueno, estás hablando muy vagamente (tiempo de ingeniería sin referencia a lo que se está diseñando, cuáles son las restricciones, etc.; bucle de retroalimentación sin referencia a lo que se está retroalimentando a quién, etc.), así que voy retirarse de esta conversación en lugar de intercambiar referencias crípticas.
Nada vago aquí. Echa un vistazo al bucle OODA o PDCA.
Stephan Eggermont
3
@user Bueno, cualquier proyecto que se ejecute una vez y que demore un mes en escribirse, y un minuto en ejecutarse, tendrá una aceleración general del 0.0% (1 mes + 1 minuto vs 1 mes) del uso de PyPy, incluso si PyPy fuera mil veces más rápido. Stephan no afirmaba que todos los proyectos tendrían un 0% de aceleración.
gmatht
4

Para simplificar esto: PyPy proporciona la velocidad que le falta a CPython pero sacrifica su compatibilidad. Sin embargo, la mayoría de las personas eligen Python por su flexibilidad y su característica de "batería incluida" (alta compatibilidad), no por su velocidad (aunque todavía se prefiere).

Yishen Chen
fuente
16
"batería incluida" significa gran biblioteca estándar , AFAIK
tshepang
4

He encontrado ejemplos, donde PyPy es más lento que Python. Pero: solo en 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

Entonces, si piensas en PyPy, olvida Windows. En Linux, puedes lograr aceleraciones increíbles. Ejemplo (enumere todos los números primos entre 1 y 1,000,000):

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

Esto se ejecuta 10 (!) Veces más rápido en PyPy que en Python. Pero no en ventanas. Ahí solo es 3 veces más rápido.

Lifolofi
fuente
¡Interesante! Algunas comparaciones y números más habrían sido geniales.
ben26941
1

PyPy ha tenido soporte para Python 3 por un tiempo, pero según esta publicación de HackerNoon de Anthony Shaw del 2 de abril de 2018 , PyPy3 sigue siendo varias veces más lento que PyPy (Python 2).

Para muchos cálculos científicos, en particular los cálculos matriciales, numpy es una mejor opción (consulte Preguntas frecuentes: ¿Debo instalar numpy o numpypy? ).

Pypy no es compatible con gmpy2. En su lugar, puede utilizar gmpy_cffi, aunque no he probado su velocidad y el proyecto tuvo un lanzamiento en 2014.

Para los problemas del Proyecto Euler, hago uso frecuente de PyPy, y para cálculos numéricos simples a menudo from __future__ import divisiones suficiente para mis propósitos, pero el soporte de Python 3 todavía se está trabajando a partir de 2018, con su mejor apuesta en Linux de 64 bits. Windows PyPy3.5 v6.0, la última versión de diciembre de 2018, está en versión beta.

qwr
fuente
0

Versiones de Python compatibles

Para citar el Zen de Python :

La legibilidad cuenta.

Por ejemplo, Python 3.7 introdujo clases de datos y Python 3.8 introdujo fstring = .

Puede haber otras características en Python 3.7 y Python 3.8 que son más importantes para usted. El punto es que PyPy no es compatible con Python 3.7 o Python 3.8 en este momento.

Martin Thoma
fuente