¿Qué bloquea Ruby, Python para obtener la velocidad Javascript V8? [cerrado]


261

¿Hay alguna característica de Ruby / Python que esté bloqueando la implementación de optimizaciones (por ejemplo, almacenamiento en caché en línea ) que tiene el motor V8?

Python está desarrollado conjuntamente por los chicos de Google, por lo que no debe ser bloqueado por patentes de software.

O esto es más bien una cuestión de recursos puestos en el proyecto V8 por Google.


66
La introspección y la sobrecarga del operador son probablemente grandes, pero no conozco a JS lo suficientemente bien como para darle una respuesta real. El proyecto PyPy es probablemente la mejor oportunidad de Python para alcanzar el tipo de velocidades JS.
ncoghlan

11
¿Tiene algún ejemplo en el que PyPy sea más lento que V8, excepto por el tiroteo en el lenguaje de la computadora, que es un juego completo (solo mire qué tan diferente se implementan las cosas en diferentes idiomas allí). ¿O es solo el campo de distorsión de la realidad de Google?
fijal

3
V8 no está a la altura de Python. Espere hasta que V8 tenga que implementar la especificación Javascript 1.8 para hacer una mejor comparación. Y en ese momento, estoy seguro de que alguien intentará implementar PyPy en la parte superior del motor V8 en lugar de Javascript.
Michael Dillon

14
¿Por qué estás tan seguro de que V8 es más rápido que Python o Ruby? A que?
jcoffland

66
V8 es absolutamente más rápido que Python / Ruby. Realice cualquier tipo de referencia que desee, desde un simple microbenchmark hasta una aplicación integral del mundo real escrita idiomáticamente en ambos entornos. Es un orden de magnitud más rápido para la mayoría de las operaciones nativas del lenguaje (es decir, cosas que no se delegan al código C en Python).
Hejazzman

Respuestas:


519

¿Qué bloquea Ruby, Python para obtener la velocidad Javascript V8?

Nada.

Bueno, vale: dinero. (Y tiempo, personas, recursos, pero si tienes dinero, puedes comprarlos).

V8 tiene un equipo de ingenieros brillantes, altamente especializados, altamente experimentados (y por lo tanto altamente remunerados) que trabajan en él, que tienen décadas de experiencia (estoy hablando individualmente, colectivamente, es más como siglos) en la creación de ejecución de alto rendimiento. motores para lenguajes dinámicos OO. Básicamente son las mismas personas que también crearon Sun HotSpot JVM (entre muchos otros).

Lars Bak, el desarrollador principal, ha estado trabajando literalmente en máquinas virtuales durante 25 años (y todas esas máquinas virtuales han llevado hasta V8), que es básicamente toda su vida (profesional). Algunas de las personas que escriben máquinas virtuales Ruby ni siquiera tienen 25 años.

¿Hay alguna característica de Ruby / Python que esté bloqueando la implementación de optimizaciones (por ejemplo, almacenamiento en caché en línea) que tiene el motor V8?

Dado que al menos IronRuby, JRuby, MagLev, MacRuby y Rubinius tienen un almacenamiento en línea monomórfico (IronRuby) o polimórfico, la respuesta es obviamente no.

Las implementaciones modernas de Ruby ya hacen una gran cantidad de optimizaciones. Por ejemplo, para ciertas operaciones, la Hashclase de Rubinius es más rápida que la de YARV. Ahora, esto no suena terriblemente emocionante hasta que te das cuenta de que la Hashclase de Rubinius está implementada en Ruby 100% puro, mientras que YARV está implementado en C. 100% optimizado a mano.

Entonces, al menos en algunos casos, ¡Rubinius puede generar un código mejor que GCC!

O esto es más bien una cuestión de recursos puestos en el proyecto V8 por Google.

Si. No solo Google. El linaje del código fuente de V8 tiene ahora 25 años. Las personas que están trabajando en V8 también crearon Self VM (hasta el día de hoy, uno de los motores dinámicos de ejecución de lenguaje OO más rápidos jamás creados), Animorphic Smalltalk VM (hasta hoy uno de los motores de ejecución de Smalltalk más rápidos jamás creados), HotSpot JVM (la JVM más rápida jamás creada, probablemente el período de VM más rápido) y OOVM (una de las VM Smalltalk más eficientes jamás creadas).

De hecho, Lars Bak, el desarrollador principal de V8, trabajó en cada uno de ellos, además de algunos otros.


1
¿Podemos tener alguna literatura de referencia sobre "Dado que al menos IronRuby, JRuby, MagLev, MacRuby y Rubinius tienen un almacenamiento en línea monomórfico (IronRuby) o polimórfico, la respuesta es obviamente no". ¿Por favor?
WDRust

14
SpiderMonkey tiene un rendimiento comparable, entonces, ¿cómo lo hizo Mozilla entonces? Tienen dinero muy limitado ...
Salman von Abbas

8
@SalmanPK: no es su primera máquina virtual, y también hay personas inteligentes trabajando en Mozilla.
Matthieu M.

3
@SalmanPK, miguel: Mozilla creó su VM JS al menos en parte mediante ingeniería inversa V8. blog.mozilla.org/dmandelin/2010/09/08/presenting-jagermonkey
Ian

2
@Ian V8 es de código abierto (licencia BSD), por lo que no es necesario realizar ingeniería inversa, solo mira lo que están haciendo.
dbkk

78

Hay mucho más ímpetu para optimizar altamente los intérpretes de JavaScript, por lo que vemos tantos recursos entre ellos entre Mozilla, Google y Microsoft. JavaScript debe descargarse, analizarse, compilarse y ejecutarse en tiempo real mientras un ser humano (generalmente impaciente) lo espera, debe ejecutarse MIENTRAS que una persona interactúa con él, y lo hace en un cliente incontrolado. entorno que podría ser una computadora, un teléfono o una tostadora. Tiene que ser eficiente para funcionar bajo estas condiciones de manera efectiva.

Python y Ruby se ejecutan en un entorno controlado por el desarrollador / implementador. Un servidor robusto o un sistema de escritorio generalmente donde el factor limitante será cosas como memoria o E / S de disco y no tiempo de ejecución. O donde se pueden utilizar optimizaciones que no sean del motor, como el almacenamiento en caché. Para estos idiomas, probablemente tenga más sentido centrarse en el conjunto de características de idioma y biblioteca sobre la optimización de la velocidad.

El beneficio adicional de esto es que tenemos dos motores JavaScript de código abierto de alto rendimiento que pueden y están siendo rediseñados para todo tipo de aplicaciones como Node.js.


43

Una buena parte tiene que ver con la comunidad. Python y Ruby en su mayor parte no tienen respaldo corporativo. A nadie se le paga por trabajar en Python y Ruby a tiempo completo (y especialmente no se les paga por trabajar en CPython o MRI todo el tiempo). V8, por otro lado, está respaldado por la compañía de TI más poderosa del mundo.

Además, V8 puede ser más rápido porque lo único que le importa a la gente de V8 es el intérprete: no tienen una biblioteca estándar para trabajar, no les preocupa el diseño del lenguaje. Simplemente escriben el intérprete. Eso es.

No tiene nada que ver con la ley de propiedad intelectual. Python tampoco está desarrollado conjuntamente por los chicos de Google (su creador trabaja allí junto con algunos otros encargados, pero no se les paga por trabajar en Python).

Otro obstáculo para la velocidad de Python es Python 3. Su adopción parece ser la principal preocupación de los desarrolladores de lenguaje, hasta el punto de que han congelado el desarrollo de nuevas características de lenguaje hasta que otras implementaciones se pongan al día.

En cuanto a los detalles técnicos, no sé mucho sobre Ruby, pero Python tiene varios lugares donde se podrían usar optimizaciones (y Unladen Swallow, un proyecto de Google, comenzó a implementarlas antes de morder el polvo). Estas son algunas de las optimizaciones que planearon . Podría ver a Python ganando velocidad V8 en el futuro si se implementa un JIT a la PyPy para CPython, pero eso no parece probable para los próximos años (el enfoque en este momento es la adopción de Python 3, no un JIT).

Muchos también sienten que Ruby y Python podrían beneficiarse enormemente al eliminar sus respectivos bloqueos de intérprete globales .

También debe comprender que Python y Ruby son lenguajes mucho más pesados ​​que JS: proporcionan mucho más en cuanto a biblioteca estándar, características de lenguaje y estructura. El sistema de clases de orientación a objetos solo agrega una gran cantidad de peso (en el buen sentido, creo). Casi pienso en Javascript como un lenguaje diseñado para ser incrustado, como Lua (y en muchos sentidos, son similares). Ruby y Python tienen un conjunto de características mucho más rico, y esa expresividad generalmente tendrá un costo de velocidad.


3
En realidad, la moratoria sobre las nuevas funciones se ha levantado desde el reciente lanzamiento de Python 3.2.
jd.

2
+1, pero ¿no congelaría las nuevas características del lenguaje significaría más tiempo para optimizar?
Andrew Grimm

1
@ Andrew si solo. La atención se centra en actualizar Jython, IronPython y PyPy, esperar que las bibliotecas se conviertan a Python 3 y evangelizar Python 3.
Rafe Kettler

2
"El sistema de clases de orientación a objetos solo agrega una gran cantidad de peso": las máquinas virtuales JavaScript modernas como V8 tienen clases, son simplemente implícitas. Al igual que en Python, no tiene que escribir explícitamente una variable en JavaScript, tampoco tiene que escribir explícitamente una clase. La VM es lo suficientemente inteligente como para revisar su código y extraer clases.
Benjamin Gruenbaum

1
Según tengo entendido, V8 es un compilador JIT en lugar de un intérprete ... Estoy bastante seguro de que hay una distinción entre los dos. Quizás no ... No lo sé.
Lucas

24

El rendimiento no parece ser el foco principal de los desarrolladores centrales de Python, quienes parecen sentir que "lo suficientemente rápido" es lo suficientemente bueno, y que las características que ayudan a los programadores a ser más productivos son más importantes que las características que ayudan a las computadoras a ejecutar el código más rápido.

De hecho, sin embargo, hubo un proyecto de Google (ahora abandonado), sin carga , para producir un intérprete de Python más rápido compatible con el intérprete estándar. PyPy es otro proyecto que pretende producir un Python más rápido. También está Psyco , el precursor de PyPy, que puede proporcionar mejoras de rendimiento a muchos scripts de Python sin cambiar todo el intérprete, y Cython , que le permite escribir bibliotecas C de alto rendimiento para Python usando algo muy parecido a la sintaxis de Python.


13

Pregunta engañosa. V8 es una implementación JIT (un compilador justo a tiempo) de JavaScript y, en su implementación más popular, Node.js, está construida alrededor de un bucle de eventos. CPython no es un JIT y no está igualado. Pero estos existen en Python más comúnmente en el proyecto PyPy: un JIT compatible con CPython 2.7 (y que pronto será 3.0+). Y hay un montón de bibliotecas de servidores con eventos como Tornado, por ejemplo. Existen pruebas del mundo real entre PyPy ejecutando Tornado vs Node.js y las diferencias de rendimiento son leves.


3
+1 por mencionar Tornado . Si bien funciona a una velocidad comparable a Node.js, su gen.enginemódulo junto con los generadores de Python y la yielddeclaración ( desde 2.5 !!! pueden redefinir su codificación asincrónica.
Lukas Bünger

1
Desde su publicación, pypy lanzó una versión compatible 3.x estable (y continúa mejorando el soporte, por supuesto): morepypy.blogspot.fr/2014/06/pypy3-231-fulcrum.html
Zeograd

9

Acabo de encontrarme con esta pregunta y también hay una gran razón técnica para la diferencia de rendimiento que no se mencionó. Python tiene un ecosistema muy grande de poderosas extensiones de software, pero la mayoría de estas extensiones están escritas en C u otros lenguajes de bajo nivel para el rendimiento y están fuertemente vinculadas a la API de CPython.

Hay muchas técnicas conocidas (JIT, recolector de basura moderno, etc.) que podrían usarse para acelerar la implementación de CPython, pero todas requerirían cambios sustanciales en la API, rompiendo la mayoría de las extensiones en el proceso. CPython sería más rápido, pero se perdería mucho de lo que hace que Python sea tan atractivo (la amplia pila de software). Por ejemplo, hay varias implementaciones de Python más rápidas, pero tienen poca tracción en comparación con CPython.


9

Debido a las diferentes prioridades de diseño y objetivos de casos de uso, creo.

En general, el propósito principal de los lenguajes de secuencias de comandos (también conocidos como dinámicos) es ser un "pegamento" entre llamadas de funciones nativas. Y estas funciones nativas deberán a) cubrir las áreas más críticas / de uso frecuente yb) ser lo más efectivas posible.

Aquí hay un ejemplo: la ordenación jQuery hace que el Safari de iOS se congele La congelación se debe al uso excesivo de llamadas get-by-selector. Si get-by-selector se implementara en código nativo y efectivamente, no sería tal problema en absoluto.

Considere la demostración de ray-tracer que se utiliza con frecuencia para la demostración de V8. En el mundo de Python, se puede implementar en código nativo ya que Python proporciona todas las facilidades para extensiones nativas. Pero en el reino V8 (sandbox del lado del cliente) no tiene otras opciones en lugar de hacer que la VM sea [sub] efectiva como sea posible. Y así, la única opción para ver la implementación de ray-tracer es mediante el uso de código de script.

Entonces diferentes prioridades y motivaciones.

En Sciter , hice una prueba implementando prácticamente el núcleo completo de jQurey de forma nativa. En tareas prácticas como ScIDE (IDE hecho de HTML / CSS / Script), creo que dicha solución funciona significativamente mejor que cualquier optimización de VM.


5

Como otras personas han mencionado, Python tiene un compilador JIT de alto rendimiento en forma de PyPy .

Hacer puntos de referencia significativos siempre es sutil, pero resulta que tengo un punto de referencia simple de K-means escrito en diferentes idiomas: puede encontrarlo aquí . Una de las limitaciones era que los diversos idiomas deberían implementar el mismo algoritmo y deberían esforzarse por ser simples e idiomáticos (en lugar de optimizados para la velocidad). He escrito todas las implementaciones, así que sé que no he hecho trampa, aunque no puedo afirmar para todos los idiomas que lo que he escrito es idiomático (solo tengo un conocimiento pasajero de algunos de ellos).

No afirmo ninguna conclusión definitiva, pero PyPy fue una de las implementaciones más rápidas que obtuve, mucho mejor que Node. CPython, en cambio, estaba en el extremo más lento de la clasificación.


5

La afirmación no es exactamente cierta

Al igual que V8 es solo una implementación para JS, CPython es solo una implementación para Python. Pypy tiene actuaciones que coinciden con V8 .

Además, existe el problema del rendimiento percibido: dado que V8 no bloquea de forma nativa, el desarrollo web conduce a proyectos más eficaces porque ahorra la espera de E / S. Y V8 se usa principalmente para desarrolladores web donde IO es clave, por lo que lo comparan con proyectos similares. Pero puede usar Python en muchas, muchas otras áreas además del desarrollador web. E incluso puede usar extensiones C para muchas tareas, como cómputos científicos o encriptación, y procesar datos con excelentes resultados.

Pero en la web, los proyectos más populares de Python y Ruby están bloqueando. Python, especialmente, tiene el legado del estándar WSGI síncrono, y los marcos como el famoso Django se basan en él.

Puedes escribir Python asíncrono (como Twisted, Tornado, gevent o asyncio) o Ruby. Pero no se hace a menudo. Las mejores herramientas todavía están bloqueando.

Sin embargo, son algunas de las razones por las cuales las implementaciones predeterminadas en Ruby y Python no son tan rápidas como V8.

Experiencia

Como Jörg W Mittag señaló, los chicos que trabajan en V8 son genios de VM. Python es dev por un grupo de personas apasionadas, muy buenas en muchos dominios, pero no están tan especializadas en el ajuste de VM.

Recursos

La fundación Python Software tiene muy poco dinero: menos de 40k en un año para invertir en Python. Esto es un poco loco cuando crees que grandes jugadores como Google, Facebook o Apple están usando Python, pero es la verdad fea: la mayoría del trabajo se hace de forma gratuita. El lenguaje que impulsa Youtube y existía antes de Java ha sido creado a mano por voluntarios.

Son voluntarios inteligentes y dedicados, pero cuando identifican que necesitan más jugo en un campo, no pueden pedir 300k para contratar a un especialista de primer nivel para esta área de especialización. Tienen que buscar a alguien que lo haga gratis.

Si bien esto funciona, significa que debes tener mucho cuidado con tus prioridades. Por lo tanto, ahora tenemos que mirar:

Objetivos

Incluso con las últimas características modernas, escribir Javascript es terrible. Tiene problemas de alcance, muy pocas colecciones, terrible manipulación de cadenas y matrices, casi ninguna lista estándar aparte de la fecha, matemáticas y expresiones regulares, y ningún azúcar sintáctico incluso para operaciones muy comunes.

Pero en V8, tienes velocidad.

Esto se debe a que la velocidad era el objetivo principal de Google, ya que es un cuello de botella para el procesamiento de páginas en Chrome.

En Python, la usabilidad es el objetivo principal. Porque casi nunca es el cuello de botella en el proyecto. El recurso escaso aquí es el tiempo del desarrollador. Está optimizado para el desarrollador.


1

Debido a que las implementaciones de JavaScript no necesitan preocuparse por la compatibilidad con versiones anteriores de sus enlaces.

Hasta hace poco, los únicos usuarios de las implementaciones de JavaScript habían sido los navegadores web. Debido a los requisitos de seguridad, solo los proveedores de navegadores web tenían el privilegio de ampliar la funcionalidad escribiendo enlaces en los tiempos de ejecución. Por lo tanto, no era necesario mantener la API C de los enlaces compatible con versiones anteriores, estaba permitido solicitar a los desarrolladores del navegador web que actualicen su código fuente a medida que evolucionaban los tiempos de ejecución de JavaScript; estaban trabajando juntos de todos modos. Incluso V8, que llegó tarde al juego y también liderado por un desarrollador muy experimentado, ha cambiado la API a medida que mejoró.

OTOH Ruby se usa (principalmente) en el lado del servidor. Muchas extensiones ruby ​​populares se escriben como enlaces C (considere un controlador RDBMS). En otras palabras, Ruby nunca hubiera tenido éxito sin mantener la compatibilidad.

Hoy, la diferencia todavía existe hasta cierto punto. Los desarrolladores que usan node.js se quejan de que es difícil mantener sus extensiones nativas compatibles con versiones anteriores, ya que V8 cambia la API con el tiempo (y esa es una de las razones por las que se ha bifurcado node.js). IIRC ruby ​​sigue adoptando un enfoque mucho más conservador a este respecto.


1

V8 es rápido debido al JIT, el cigüeñal, el inferenciador de tipos y el código optimizado para datos. Punteros etiquetados, marcado NaN de dobles. Y, por supuesto, hace optimizaciones de compilador normales en el medio.

Los motores ruby, python y perl simples no hacen ninguno de esos, solo optimizaciones básicas menores.

El único vm principal que se acerca es luajit, que ni siquiera hace inferencia de tipos, plegado constante, etiquetado NaN ni números enteros, sino que usa códigos pequeños similares y estructuras de datos, no tan gruesas como los malos lenguajes. Y mis prototipos de lenguajes dinámicos, poción y p2 tienen características similares a luajit, y superan a v8. Con un sistema de tipo opcional, "mecanografía gradual", podría superar fácilmente a v8, ya que puede evitar el cigüeñal. Ver dardo.

Los backends optimizados conocidos, como pypy o jruby, todavía sufren varias técnicas de ingeniería excesiva.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.