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

¿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 por Google, por lo que no debería ser bloqueado por las patentes de software.

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

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

Nada.

Bueno, está bien: el dinero. (Y tiempo, gente, recursos, pero si tienes dinero, puedes comprarlos).

V8 tiene un equipo de ingenieros shinys, altamente especializados, altamente experimentados (y, por lo tanto, altamente remunerados) que trabajan en él, que cuentan con décadas de experiencia (hablo individualmente, colectivamente es como siglos) en la creación de una ejecución de alto rendimiento. Motores para lenguajes dynamics OO. Básicamente, son las mismas personas que también crearon el Sun HotSpot JVM (entre muchos otros).

Lars Bak, el desarrollador líder, ha estado literalmente trabajando en máquinas virtuales durante 25 años (y todas esas máquinas virtuales han llevado a V8), que es básicamente su vida (profesional). Algunas de las personas que escriben máquinas virtuales de Ruby no tienen ni siquiera 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 almacenamiento en caché en línea monomórfico (IronRuby) o polimórfico, la respuesta es obviamente no.

Las implementaciones modernas de Ruby ya hacen muchas optimizaciones. Por ejemplo, para ciertas operaciones, la clase Hash 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 clase Hash de Rubinius se implementa en Ruby 100% puro, mientras que la YARV se implementa en C 100% optimizada a mano.

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

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

Sí. No solo Google. El linaje del código fuente de V8 tiene ahora 25 años. Las personas que trabajan en V8 también crearon el Self VM (hasta el día de hoy uno de los motores de ejecución OO dynamics más rápidos jamás creados), el VM Smalltalk animorphic (hasta el día de hoy uno de los motores de ejecución Smalltalk más rápidos jamás creados), el 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 de 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.

Hay mucho más ímpetu para optimizar los interpretadores de JavaScript, por eso vemos tantos recursos entre Mozilla, Google y Microsoft. JavaScript debe descargarse, analizarse, comstackrse y ejecutarse en tiempo real mientras que un ser humano (generalmente impaciente) lo está esperando, tiene que correr MIENTRAS que una persona esté interactuando con él, y está haciendo esto en un cliente no controlado. 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 de gran tamaño o un sistema de escritorio generalmente donde el factor limitante serán cosas como la memoria o la E / S del disco y no el tiempo de ejecución. O donde se pueden utilizar optimizaciones no relacionadas con el motor, como el almacenamiento en caché. Para estos idiomas es probable que tenga más sentido centrarse en el conjunto de funciones de la biblioteca y el idioma sobre la optimización de la velocidad.

El beneficio adicional de esto es que tenemos dos motores JavaScript de código abierto de gran rendimiento que pueden ser reutilizados para todo tipo de aplicaciones como Node.js.

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 para trabajar en Python y Ruby a tiempo completo (y especialmente a ellos no se les paga para que trabajen 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 en la que trabajar, ni preocupaciones sobre el diseño del idioma. Sólo escriben el intérprete. Eso es.

No tiene nada que ver con la ley de propiedad intelectual. Python tampoco es un co-desarrollado por los chicos de Google (su creador trabaja allí junto con algunos otros comprometidos, pero no se les paga para que trabajen 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 lenguajes, 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 una serie de lugares donde se pueden usar optimizaciones (y Unladen Swallow, un proyecto de Google, comenzó a implementar estos 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 creen que Ruby y Python podrían beneficiarse enormemente de la eliminación de sus respectivos lockings globales de intérprete .

También debe comprender que Python y Ruby son lenguajes mucho más pesados ​​que JS; proporcionan mucho más en cuanto a bibliotecas estándar, características del idioma y estructura. El sistema de clases de orientación a objetos por sí solo agrega una gran cantidad de peso (creo que de una buena manera). 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 usualmente va a tener el costo de la velocidad.

El rendimiento no parece ser un enfoque importante de los desarrolladores centrales de Python, que parecen sentir que “lo suficientemente rápido” es lo suficientemente bueno, y que las características que ayudan a los progtwigdores a ser más productivos son más importantes que las 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), unladen-swallow , 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 en el rendimiento de muchos scripts de Python sin cambiar todo el intérprete, y Cython , que le permite escribir bibliotecas de C de alto rendimiento para Python utilizando algo muy parecido a la syntax de Python.

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

Acabo de encontrar esta pregunta y también hay una gran razón técnica para la diferencia de rendimiento que no se mencionó. Python tiene un gran ecosistema 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.

Existen muchas técnicas bien 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 extensa stack de software). Por ejemplo, hay varias implementaciones más rápidas de Python pero tienen poca tracción en comparación con CPython.

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

En general, el propósito principal de los lenguajes de scripting (también conocido como dynamic) es ser un “pegamento” entre las llamadas de funciones nativas. Y estas funciones nativas deberán a) cubrir la mayoría de las áreas críticas / de uso frecuente yb) ser lo más eficaces posible.

A continuación se muestra un ejemplo: la ordenación jQuery que hace que iOS Safari se congele La congelación allí es causada por el uso excesivo de llamadas de obtención de selector. Si get-by-selector se implementara en código nativo y efectivamente no será un problema de este tipo.

Considere la demo de ray-tracer que se usa 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 (recinto de seguridad del lado del cliente) no tiene más opciones que hacer que la VM sea [sub] lo más efectiva posible. Y así, la única opción es ver la implementación de ray-tracer usando un código de script.

Tan diferentes prioridades y motivaciones.

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

Como otras personas han mencionado, Python tiene un comstackdor JIT ejecutante 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; lo puedes encontrar aquí . Una de las restricciones fue que todos los idiomas deberían implementar el mismo algoritmo y 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 engañado, aunque no puedo afirmar en todos los idiomas que lo que he escrito es idiomático (solo conozco algunos de ellos).

No reclamo 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.

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, ahí está el problema del rendimiento percibido: dado que V8 no está bloqueado de forma nativa, el desarrollador web lleva a proyectos más eficaces porque guarda la espera de IO. Y V8 se usa principalmente para dev Web donde IO es clave, por lo que lo comparan con proyectos similares. Pero puedes usar Python en muchas, muchas otras áreas además del desarrollo web. E incluso puede usar las extensiones C para muchas tareas, como los cálculos científicos o el cifrado, y procesar datos con resultados increíbles.

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

Puede escribir Python asíncrono (como con Twisted, Tornado, gevent o asyncio) o Ruby. Pero no se hace a menudo. Las mejores herramientas siguen bloqueando.

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

Experiencia

Como señaló Jörg W Mittag, los tipos que trabajan en V8 son genios de máquinas virtuales. Python es un grupo de personas apasionadas, muy buenas en muchos dominios, pero no están tan especializadas en la optimización 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 piensas que grandes jugadores como Google, Facebook o Apple están usando Python, pero es la fea verdad: la mayoría del trabajo se hace de forma gratuita. El lenguaje que impulsa a Youtube y existió antes de que Java haya sido creado por voluntarios.

Son voluntarios inteligentes y dedicados, pero cuando identifican que necesitan más jugo en un campo, no pueden solicitar 300k para contratar a un especialista de primera categoría para esta área de experiencia. 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:

Los objectives

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

Pero en V8, tienes velocidad.

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

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

Porque las implementaciones de JavaScript no tienen que preocuparse por la compatibilidad hacia atrás de sus enlaces.

Hasta hace poco, los únicos usuarios de las implementaciones de JavaScript han sido los navegadores web. Debido a los requisitos de seguridad, solo los proveedores de navegadores web tuvieron el privilegio de ampliar la funcionalidad escribiendo enlaces a los tiempos de ejecución. Por lo tanto, no era necesario mantener la API de C de los enlaces compatibles con versiones anteriores, estaba permitido solicitar a los desarrolladores del navegador web que actualizaran 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, cambió la API a medida que mejoraba.

OTOH Ruby se utiliza (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 en día, la diferencia todavía existe en cierta medida. 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 a lo largo del tiempo (y esa es una de las razones por las que node.js ha sido bifurcada). El Ruby IIRC todavía está adoptando un enfoque mucho más conservador a este respecto.

V8 es rápido debido al JIT, el cigüeñal, el inferencio de tipo y el código optimizado de datos. Punteros etiquetados, etiquetado NaN de dobles. Y, por supuesto, hace las optimizaciones normales del comstackdor en el medio.

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

El único vm importante que se acerca es luajit, que ni siquiera hace inferencia de tipos, plegado constante, etiquetado NaN ni enteros, sino que utiliza un código pequeño similar y estructuras de datos, no tan gruesas como las malas lenguas. Y mi prototipo de lenguajes dynamics, potion y p2 tienen características similares a luajit, y superan a v8. Con un sistema de tipo opcional, “escritura gradual”, podría superar fácilmente a v8, ya que puede evitar el cigüeñal. Ver dardo.

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