2010-01-26 19 views
50

Estoy confundido acerca de los motores de JavaScript en este momento. Sé que V8 fue un gran problema porque compiló JavaScript para el código nativo.Javascript Engines Ventajas

Luego comencé a leer acerca de Mozilla SpiderMonkey, que por lo que entiendo está escrito en C y puede compilar JavaScript. Entonces, ¿cómo es esto diferente de V8 y si esto es cierto, por qué Firefox no hace esto?

Finalmente, ¿Rhino literalmente compila el código de bytes de JavaScript a Java para que pueda obtener todas las ventajas de velocidad de Java? Si no es así, ¿por qué las personas no ejecutan V8 cuando escriben scripts en sus escritorios?

+1

Rhino puede compilar el código de bytes de Java. https://developer.mozilla.org/es/Rhino_JavaScript_Compiler – Thilo

Respuesta

8

V8 es el más rápido, porque compila todo el JS al código de máquina.

SpiderMonkey (lo que FF usa) también es rápido, pero se compila a un byte intermedio, no a un código de máquina. Esa es la gran diferencia con V8. EDITAR- Los lanzamientos más nuevos de Firefox vienen con una variante más nueva de SpideMonkey; TraceMonkey. TraceMonkey hace compilación JIT de partes críticas, y tal vez otras optimizaciones inteligentes.

Rhino compila Javascript en clases Java, lo que le permite básicamente escribir aplicaciones "Java" en Javascript. Rhino también se usa como una forma de interpretar JS en el backend y manipularlo, y tener una comprensión completa del código, como la reflexión. Esto es usado, por ejemplo, por el compresor YUI. El motivo por el que se utiliza Rhino en lugar de V8 es probablemente porque V8 es relativamente nuevo, por lo que muchos proyectos ya han utilizado Rhino/Spidermonkey como motor JS, por ejemplo, widgets de Yahoo. (Supongo que eso es a lo que se refiere con "secuencias de comandos en sus equipos de escritorio")

edit- Este enlace también puede dar una idea de por qué SpiderMonkey es tan ampliamente adoptado. Which Javascript engine would you embed in your application?

+2

Umm TraceMonkey también hace la traducción de JIT al código de máquina ... También, no creo que sea preciso decir que V8 "compila" JavaScript a código de máquina - es más o menos el mismo tipo de enfoque JIT que TraceMonkey. – Pointy

+0

@Pointy, la diferencia AFAIK entre TraceMonkey y V8 es que TraceMonkey se compila en código intermedio, algunos de los cuales obtienen JIT compilado en código máquina a medida que se ejecuta. V8 compila todo directamente al código de máquina. –

+1

"V8 compila el código fuente de JavaScript directamente en el código de máquina cuando se ejecuta por primera vez. No hay códigos de bytes intermedios, no hay intérprete". Fuente: http://code.google.com/apis/v8/design.html Así que básicamente la compilación como un compilador de C sería suficiente. Además, V8 compila todos los JS, y TraceMonkey hace JIT – adamJLev

3

Para responder a la pregunta, ¿por qué código nativo Vs código de bytes ...

El código nativo es más rápido y por google una elección estratégica, ya que tienen plan para JS uno de ellos al menos es Chrome.

Un buen video sobre esta cuestión se publica en Channel9 con una entrevista a Lars Bak el hombre detrás V8 se puede encontrar here

6

Si desea ver cómo los diferentes en el navegador motores de JavaScript apilan, instalar Safari 4 (sí que se ejecuta en windows ahora también!), Chrome V8, Firefox 3.5, y el IE 8 (si está en windows) y ejecuta el punto de referencia:

http://www2.webkit.org/perf/sunspider-0.9/sunspider.html

creo que dijeron puntiagudo anterior, la El nuevo Firefox 3.5 usa TraceMonkey que también se compila para intermediar código sobre la marcha usando algunos f orm de JIT. Por lo tanto, debería compararse con V8 de manera un tanto favorable. Al menos no será 10 veces más lento que V8 como lo fue Firefox 3 SpiderMonkey (sin JIT).

Para mí ... safari 4.0.3 era 2.5 veces más rápido que Tracemonky en Firefox 3.5.3 en Win XP. IE8 fue mucho más lento. No tengo Chrome instalado en este momento.

No sabe acerca de la compilación de Rhino a bytecode de java. Si todavía está interpretando las características dinámicas de Javascript, como poder agregar atributos a instancias de objetos en tiempo de ejecución (ejemplo obj.someNewAttribute = "someValue", que está permitido en Javascript) ...No estoy tan seguro de que esté completamente "compilado" para bytecode, y es posible que no obtengas un mejor rendimiento que no sea necesario compilar a partir del texto del código fuente de Javascript cada vez que se ejecute tu Javascript. Recuerde que Javascript permite una sintaxis muy dinámica como eval ("x = 10; y = 20; z = x * y"); lo que significa que puede construir cadenas de código que se compilan en el tiempo de ejecución. Es por eso que creo que Rhino sería interpretado/compilado en modo mixto, incluso si compiló código byte de JVM.

La JVM sigue siendo un intérprete, aunque una muy buena con el soporte de JIT. Así que me gusta pensar en Rhino-on-JVM como 2 capas de intérprete (intérprete-en-intérprete) o intérprete^2. Mientras que la mayoría de sus otros motores Javascript están escritos en C, y como tales deberían interpretarse más como intérprete^1. Cada capa de intérprete puede agregar una degradación de rendimiento de 5-10x en comparación con C o C++ (ref. Perl o Python o Ruby, por ejemplo), pero con JIT, el rendimiento puede ser mucho menor del orden de 2-4x. Y la JVM tiene uno de los motores JIT maduros más robustos &.

Así que su kilometraje variará definitivamente y probablemente se beneficiaría de hacer algunos puntos de referencia serios si quiere una respuesta real para su aplicación prevista en su propio hardware & OS.

Rhino no puede ser demasiado lento, ya que sé que mucha gente lo está usando. Creo que su principal atractivo no es su velocidad, sino el hecho de que es fácil de codificar/ligero/incrustable/intérprete que tiene ganchos en las bibliotecas de Java, lo que lo hace perfecto para la creación de scripts/configuración/extensibilidad de su proyecto de software. Algunos editores de texto como UltraEdit incluso están incorporando Javascript como un motor de macro scripting alternativo. Todos los programadores parecen ser capaces de tropezar a través de JavaScript con bastante facilidad, por lo que es fácil de recuperar también.

Una de las ventajas de Rhino es que se ejecuta prácticamente en cualquier lugar donde se ejecute la JVM. En mi experiencia, tratar de hacer funcionar TraceMonkey o SpiderMonkey por separado para compilar & ejecutar desde la línea de comandos puede ser un poco doloroso en sistemas como Windows. Y la incrustación en su propia aplicación puede consumir aún más tiempo. Pero la recompensa por tener un lenguaje incrustado valdría la pena para un gran proyecto, en comparación con tener que "rodar tu propio" mini scripting solution si eso es lo que estás buscando hacer.

Hacer scripts con Rhino es muy fácil si tiene Java y el contenedor de rinocerontes, solo tiene que escribir su javascript y ejecutarlo desde la línea de comandos. Lo uso todo el tiempo para tareas simples.

+0

Instalé Chrome 4 en mi máquina XP, y ejecuta los puntos de referencia sunspider aproximadamente 3 veces más rápido que Firefox 3.5.3 Tracemonkey. También descubrí que V8 es agradablemente fácil de descargar y construir en comparación con mi experiencia previa con SpiderMonkey. Por supuesto que necesitas svn + python 2.4 + scons 1.0.0 + Visual Studio 2005/2008 (la versión gratuita de VC++ 2008 supuestamente funciona también), todas las cuales ya tenía ejecutadas en mi PC. Para ser justos, tal vez regrese y pruebe la compilación de TraceMonkey nuevamente y vea cómo se acumula hoy en día. – linguanerd

+3

Tenga en cuenta que Sunspider no es la única respuesta, es solo un punto de referencia de JavaScript (aunque uno que los autores de motores de JavaScript han optimizado en gran medida). –

+0

VC++ 2008 express (gratis) funciona para compilar v8 con scons, lo hizo a principios de esta semana. –

73

Hay varios enfoques para la ejecución de JavaScript, incluso cuando se ejecuta JIT. V8 y Nitro (anteriormente conocido como SquirrelFish Extreme) eligen hacer un JIT de método completo, lo que significa que compilan todos los códigos de JavaScript siguiendo instrucciones nativas cuando encuentran secuencias de comandos, y luego simplemente lo ejecutan como si se tratara de código C compilado. SpiderMonkey utiliza en su lugar un JIT de "rastreo", que primero compila el script para que lo transmita e interprete, pero supervisa la ejecución, buscando "puntos calientes" como bucles. Cuando detecta uno, compila solo esa ruta caliente al código de máquina y lo ejecuta en el futuro.

Ambos enfoques tienen ventajas y desventajas. El JIT de método completo garantiza que todo el código JavaScript que se ejecuta se compilará y ejecutará como código de máquina y no se interpretará, lo que en general debería ser más rápido. Sin embargo, dependiendo de la implementación, puede significar que el motor dedique tiempo a compilar código que nunca se ejecutará, o solo se puede ejecutar una vez, y no es crítico para el rendimiento. Además, este código compilado debe almacenarse en la memoria, por lo que esto puede conducir a un mayor uso de la memoria.El JIT de seguimiento implementado en SpiderMonkey puede producir código extremadamente especializado en comparación con un JIT de método completo, ya que ya ha ejecutado el código y puede especular sobre los tipos de variables (como tratar la variable de índice en un bucle for). como un entero nativo), donde un JIT de método completo tendría que tratar la variable como un objeto porque JavaScript está sin tipo y el tipo podría cambiar (SpiderMonkey simplemente se "caiga" de rastreo si la suposición falla, y vuelve a interpretar bytecode) . Sin embargo, el JIT de rastreo de SpiderMonkey actualmente no funciona de manera eficiente en código con muchas ramas, ya que las trazas están optimizadas para rutas de ejecución únicas. Además, hay una sobrecarga implicada en la supervisión de la ejecución antes de decidir compilar una traza y luego cambiar la ejecución a esa traza. Además, si el rastreador hace una suposición que luego se viola (como un tipo de cambio de variable), es probable que el costo de la caída del rastreo y el cambio a la interpretación sea mayor que con un JIT de método completo.

+8

Tenga en cuenta que en los años intermedios, Firefox ha cambiado a usar un JIT de método completo, así como "JaegerMonkey" y ha eliminado el JIT de rastreo. –