Análisis ANTLR de archivo Java 8 (enlace de Python) – tiempo de ejecución lento.
Estoy intentando escanear un archivo de Java 8 con antlr4, basado en esta gramática de Java 8. Todo va bien, excepto el tiempo de ejecución:
input<em>stream = FileStream("/main.java")
lexer = Java8Lexer(input</em>stream)
stream = CommonTokenStream(lexer)
parser = Java8Parser(stream)
tree = parser.compilationUnit()
class GadgetIfStmtListener(Java8Listener):
# Ingresa en un árbol de análisis producido por Java8Parser #ifThenStatement.
def enterIfThenStatement(self, ctx:Java8Parser.IfThenStatementContext):
print(ctx.getText())
gadget = GadgetIfStmtListener()
walker = ParseTreeWalker()
walker.walk(gadget, tree)
<code>
El archivo `main.java` se encuentra al final (un bucle anidado simple para calcular números primos en `[2,100]`). Cuando lo mide el tiempo, obtengo:
</code>
$ time python3.6 main.py
if(i*j==p){returnfalse;}
if(isPrime(p)){System.out.format("%d\n",p);}
real 0m14.611s
¿Es esto razonable? El documento original de pldi menciona (uno de los ejemplos es Java 1.5
)
la velocidad de análisis promedio es de alrededor de 26,000 líneas / segundo para […] ejemplos
Aquí está el archivo main.java
para completitud:
class main {
private static boolean isPrime(int p)
{
for (int i=0;i<p;i++) {
for (int j=0;j<p;j++) {
if (i*j == p) {
return false; }}}
return true;
}
private static void printPrimes(int start, int end)
{
for (int p=start;p<=end;p++) {
if (isPrime(p)) {
System.out.format("%d\n", p);
}}
}
public static void main(String[] args)
{
int start = 2;
int end = 100;
printPrimes(start, end);
System.out.println("¡Hola, mundo!");
}
}
davy.ai
El tiempo de ejecución de 14.611 segundos para analizar un simple programa en Java que consta de solo 23 líneas de código parece poco razonable. Según el documento original, la velocidad promedio de análisis para Java 1.5 era de alrededor de 26,000 líneas por segundo para ejemplos similares.
El problema podría estar relacionado con el hecho de que el archivo de entrada se lee desde el disco para cada invocación del programa. Esto se puede evitar utilizando un objeto
StringIO
en lugar de una secuencia de archivos.Otra posible razón para el rendimiento lento podría ser la complejidad de la gramática y el hecho de que la implementación de
ANTLR4
dePython
es más lenta que la implementación deJava
.También vale la pena investigar la posibilidad de utilizar una gramática más simple o reducir el alcance del programa de entrada para mejorar el rendimiento de análisis.