Ok. Aquí está mi opinión sobre por qué?
Si convierte a ambas secuencias de comandos de código de bytes, se puede observar que
- ForInLoop utiliza rango. El iterador se usa para avanzar durante cada ciclo. La comparación (<) se realiza directamente en int (o Integer) para determinar si se cumplió o no la condición de salida
- ForLoop usa el incremento tradicional, comprueba las condiciones y realiza acciones. Para comprobar la condición i < 10000000, usa el ScriptBytecodeAdapter de Groovy .compareLessThan. Si usted cava profundamente en el código de ese método, se encuentra a ambos lados de la comparación se toma en como objeto y hay tantas cosas que suceden, fundición, comparándolos como objeto, etc.
ScriptBytecodeAdapter .compareLessThan - >ScriptBytecodeAdapter .compareTo ->DefaultTypeTransformation .compareTo
Hay otras clases en el paquete typehandling que implementa el método compareTo específicamente para los tipos de datos de matemáticas, no está seguro de por qué no se están utilizando, (si es que no están siendo utilizados)
Sospecho que ese es el motivo por el que el segundo ciclo tarda más. De nuevo, por favor corrígeme si me equivoco o me falta algo ...
Eso casi lo explica. Sé que Java-style for loop ofrece más flexibilidad en lo que puede hacer, pero seguramente podrían haber aplicado alguna optimización a su forma más básica (y la más utilizada) para que funcione tan bien como el bucle for..in? Esa es una pequeña trampa de rendimiento para las personas que vienen de Java o C# ... – Xiaofu
Nadie espera tanta disparidad en estas dos operaciones. Áreas donde Groovy podría mejorar, especialmente dado que un código similar en Java se ejecuta en 300 mS. –
+1 para mirar el bytecode. – Leonel