2012-07-11 32 views
11

Estoy trabajando en mi propio lenguaje de programación de juguetes. Por ahora estoy interpretando el lenguaje de origen de AST y me pregunto qué ventajas puedo obtener al compilar un código de bytes y luego interpretarlo.¿Cuáles son las motivaciones detrás de compilar a byte-code?

Por ahora tengo tres cosas en mente:

  • recorrer el árbol de sintaxis cientos de tiempo puede ser más lenta que la ejecución de instrucciones en una matriz, especialmente si el soporte de regleta de O (1) de acceso aleatorio (es decir. saltando 10 instrucciones arriba y abajo).
  • En el entorno de ejecución tipeado, tengo algunos costos de tiempo de ejecución porque mi AST está tipeado, y lo estoy recorriendo constantemente (es decir, tengo 10 tipos de nodos y necesito verificar de qué tipo estoy ahora para ejecutar). Tal vez la compilación de un código de bytes sin tipo podría ayudar a mejorar esto, ya que después de la verificación de tipos y la compilación, tendría un código y valores sin tipo.
  • La compilación del código de bytes puede proporcionar una mejor portabilidad.

¿Son correctos mis puntos? ¿Cuáles son algunas otras motivaciones detrás de la compilación de bytecode?

+0

Al ejecutar en un intérprete aumenta la portabilidad de su código – Luis

+0

@Luis, si esto ya estaba en mi mente, olvidé agregar ... – sinan

+0

@Luis: eso es falso. Los AST serializados se pueden hacer igualmente portátiles. Bytecode puede de hecho no ser portátil; El bytecode de Python es específico para cada versión del intérprete. –

Respuesta

5

La velocidad es la razón principal; interpretar AST es demasiado lento en la práctica.

Otra razón para usar bytecode es que se puede serializar trivialmente (almacenar en el disco), para que pueda distribuirlo. Esto es lo que hace Java.

+0

hmm, así que básicamente es esto. Esperaba encontrar otras motivaciones interesantes. – sinan

+0

"Esto es lo que hace Java". Python no? –

6

El objetivo de generar código de bytes (o cualquier otra forma de "interpretación fácil" como el código de subproceso) es esencialmente el rendimiento.

Para que un intérprete de AST decida qué hacer a continuación, necesita atravesar el árbol, inspeccionar los nodos, determinar el tipo de nodos, verificar el tipo de operandos, verificar la legalidad y decidir qué caso especial de AST- El operador designado aplica (dice "+", pero significa 16 bit add o string concatenate?), antes de que finalmente realice alguna acción.

Si uno realiza la acción final y genera algún tipo de estructura fácilmente interpretable, entonces en el momento de "ejecución" el intérprete puede centrarse simplemente en realizar acciones sin toda esa verificación/determinación de caso especial.

Otra excusa reciente es que si genera código de bytes para una serie de máquinas virtuales conocidas (JVM, MSIL, Parrot, etc.) ni siquiera tiene que codificar el intérprete. Para JVM y MSIL, también obtendrá el beneficio de los compiladores JIT asociados a ellos, y con un diseño cuidadoso de su idioma, compatibilidad con enormes bibliotecas, que son la verdadera atracción de Java y C#.

Cuestiones relacionadas