usar una programas matriz matrices llenar imprimir for cuadrada como ciclo java performance arrays iteration

una - matriz de matrices java



moderno para bucle para matriz primitiva (5)

¿Por qué no medirlo usted mismo?

Esto suena un poco duro, pero este tipo de preguntas son muy fáciles de verificar.

Simplemente cree la matriz y ejecute cada ciclo 1000 o más veces, y mida la cantidad de tiempo. Repita varias veces para eliminar problemas técnicos.

¿Hay alguna diferencia de rendimiento entre los bucles for en una matriz primitiva?

Asumir:

double[] doubleArray = new double[300000]; for (double var: doubleArray) someComplexCalculation(var);

o:

for ( int i = 0, y = doubleArray.length; i < y; i++) someComplexCalculation(doubleArray[i]);

Resultado de la prueba

De hecho, lo perfilé:

Total timeused for modern loop= 13269ms Total timeused for old loop = 15370ms

Entonces, el bucle moderno realmente funciona más rápido, al menos en mi Mac OSX JVM 1.5.


Mi opinión es que no sabes y no debes adivinar. Tratar de burlar a los compiladores en estos días es infructuoso.

Hubo momentos en que la gente aprendió "Patrones" que parecían optimizar alguna operación, pero en la próxima versión de Java esos patrones fueron más lentos.

Siempre escríbelo tan claro como sea posible y no se preocupe por la optimización hasta que tenga alguna especificación de usuario en su mano y no cumpla con algún requisito, e incluso entonces tenga mucho cuidado de ejecutar pruebas antes y después para asegurarse de que su El "arreglo" realmente lo mejoró lo suficiente como para hacer que ese requisito pase.

El compilador puede hacer cosas increíbles que realmente te volarán los calcetines, e incluso si realizas una prueba que itera sobre un rango grande, puede funcionar de manera completamente diferente si tienes un rango más pequeño o cambiar lo que sucede dentro del ciclo.

Justo a tiempo la compilación significa que ocasionalmente puede superar a C, y no hay ninguna razón por la que no pueda superar el lenguaje ensamblador estático en algunos casos (el ensamblado no puede determinar de antemano que una llamada no es necesaria, Java puede hacer eso precisamente.

Para resumir: el mayor valor que puede poner en su código es escribirlo para que sea legible.


No hay diferencia. Java transformará el mejorado for en el ciclo for normal. El mejorado para solo es un "azúcar de sintaxis". El bytecode generado es el mismo para ambos bucles.


Su formulario "antiguo" escrito a mano ejecuta menos instrucciones, y puede ser más rápido, aunque tendría que perfilarlo bajo un compilador JIT determinado para estar seguro. La "nueva" forma definitivamente no es más rápida.

Si observa el código desensamblado (compilado por Sun''s JDK 1.5), verá que el formulario "nuevo" es equivalente al siguiente código:

1: double[] tmp = doubleArray; 2: for (int i = 0, y = tmp.length; i < y; i++) { 3: double var = tmp[i]; 4: someComplexCalculation(var); 5: }

Entonces, puede ver que se usan más variables locales. La asignación de doubleArray a tmp en la línea 1 es "extra", pero no ocurre en el ciclo, y probablemente no se puede medir. La asignación a var en la línea 3 también es extra. Si hay una diferencia en el rendimiento, esto sería responsable.

La línea 1 puede parecer innecesaria, pero es una repetición del resultado si la matriz se calcula con un método antes de ingresar al ciclo.

Dicho esto, usaría el nuevo formulario, a menos que necesite hacer algo con la variable de índice. Es probable que el compilador JIT optimice cualquier diferencia de rendimiento en el tiempo de ejecución, y la nueva forma es más clara. Si continúa haciéndolo "a mano", puede perder optimizaciones futuras. En general, un buen compilador puede optimizar bien el código "estúpido", pero tropieza con el código "inteligente".


Tengo mucha curiosidad sobre tu pregunta, incluso después de mi respuesta anterior. Así que decidí verificarlo yo también. Escribí este pequeño fragmento de código (ignore la corrección matemática para verificar si un número es primordial ;-)):

public class TestEnhancedFor { public static void main(String args[]){ new TestEnhancedFor(); } public TestEnhancedFor(){ int numberOfItems = 100000; double[] items = getArrayOfItems(numberOfItems); int repetitions = 0; long start, end; do { start = System.currentTimeMillis(); doNormalFor(items); end = System.currentTimeMillis(); System.out.printf("Normal For. Repetition %d: %d/n", repetitions, end-start); start = System.currentTimeMillis(); doEnhancedFor(items); end = System.currentTimeMillis(); System.out.printf("Enhanced For. Repetition %d: %d/n/n", repetitions, end-start); } while (++repetitions < 5); } private double[] getArrayOfItems(int numberOfItems){ double[] items = new double[numberOfItems]; for (int i=0; i < numberOfItems; i++) items[i] = i; return items; } private void doSomeComplexCalculation(double item){ // check if item is prime number for (int i = 3; i < item / 2; i+=2){ if ((item / i) == (int) (item / i)) break; } } private void doNormalFor(double[] items){ for (int i = 0; i < items.length; i++) doSomeComplexCalculation(items[i]); } private void doEnhancedFor(double[] items){ for (double item : items) doSomeComplexCalculation(item); } }

Al ejecutar la aplicación, obtuve los siguientes resultados para mí:

Normal para. Repetición 0: 5594 Mejorado para. Repetición 0: 5594

Normal para. Repetición 1: 5531 Mejorado para. Repetición 1: 5547

Normal para. Repetición 2: 5532 Mejorado para. Repetición 2: 5578

Normal para. Repetición 3: 5531 Mejorado para. Repetición 3: 5531

Normal para. Repetición 4: 5547 Mejorado para. Repetición 4: 5532

Como podemos ver, la variación entre los resultados es muy pequeña, y algunas veces el ciclo normal se ejecuta más rápido, a veces el ciclo mejorado es más rápido. Como hay otras aplicaciones abiertas en mi computadora, me parece normal. Además, solo la primera ejecución es más lenta que las demás; creo que esto tiene que ver con las optimizaciones de JIT.

Los tiempos promedio (excluyendo la primera repetición) son 5535,25 ms para el ciclo normal y 5547 ms para el ciclo mejorado. Pero podemos ver que los mejores tiempos de ejecución para ambos bucles son los mismos (5531 ms), así que creo que podemos llegar a la conclusión de que ambos bucles tienen el mismo rendimiento, y las variaciones de tiempo transcurren debido a otras aplicaciones (incluso el sistema operativo) de la máquina.