He encontrado la siguiente anotación de bucle en un gran proyecto en el que estoy trabajando (pseudocódigo):
var someOtherArray = [];
for (var i = 0, n = array.length; i < n; i++) {
someOtherArray[i] = modifyObjetFromArray(array[i]);
}
Lo que me llamó la atención es esta variable "n" adicional. Nunca antes había visto un for lop escrito de esta manera.
Obviamente, en este escenario, no hay ninguna razón por la cual este código no se pueda escribir de la siguiente manera (a lo que estoy muy acostumbrado):
var someOtherArray = [];
for (var i = 0; i < array.length; i++) {
someOtherArray[i] = modifyObjetFromArray(array[i]);
}
Pero me dejó pensando.
¿Hay algún escenario en el que escribir un bucle for tenga sentido? Se me ocurre la idea de que la longitud de la "matriz" puede cambiar durante la ejecución del bucle for, pero no queremos hacer un bucle más allá del tamaño original, pero no puedo imaginar tal escenario.
Reducir la matriz dentro del bucle tampoco tiene mucho sentido, porque es probable que obtengamos OutOfBoundsException.
¿Existe un patrón de diseño conocido donde esta anotación sea útil?
Editar Como señaló @ Jerry101, la razón es el rendimiento. Aquí hay un enlace a la prueba de rendimiento que he creado: http://jsperf.com/ninforloop . En mi opinión, la diferencia no es lo suficientemente grande a menos que esté iterando a través de una matriz muy grande. El código del que lo copié solo tenía hasta 20 elementos, por lo que creo que la legibilidad en este caso supera la consideración de rendimiento.
fuente
n
puede ser más lenta que la que usa,array.Length
ya que el JITter podría no notar que podría eliminar las verificaciones de los límites de la matriz.Respuestas:
La variable
n
garantiza que el código generado no recupere la longitud de la matriz para cada iteración.Es una optimización que puede marcar la diferencia en el tiempo de ejecución dependiendo del idioma utilizado, si la matriz es en realidad un objeto de colección o una "matriz" de JavaScript, y otros detalles de optimización.
fuente
n
al bucle, lo que suele ser algo bueno. Lo definiría antes del ciclo solo si quisiera usarlo nuevamente más tarde.La obtención de la longitud de la matriz puede ser fácilmente "más costosa" que la acción real sobre la que se repite.
Entonces, si el conjunto no cambia, solo consulte la longitud una vez.
No con matrices, sino con conjuntos de registros provenientes de un servidor sql. He visto mejoras dramáticas al no consultar el recuento de registros en cada iteración. (por supuesto, haga esto solo si puede garantizar que la matriz o el conjunto de registros no se modifique durante este proceso).
fuente
Las personas que hablan sobre el rendimiento probablemente estén en lo cierto porque esta es la razón por la que se escribió de esa manera (la persona que lo escribió de esa manera podría no ser correcta porque afecta significativamente el rendimiento, pero ese es otro asunto).
Sin embargo, para responder a esta parte de su pregunta, creo que es más probable que suceda cuando el propósito principal del bucle es modificar la matriz sobre la que se repite. Considere algo como esto, en pseudocódigo:
Por supuesto que hay otras formas de escribirlo. En este caso, podría haber verificado los más al mismo tiempo que verificaba si los destinatarios aceptaban sus invitaciones y produje la lista completa de invitados una invitación a la vez. No necesariamente quiero combinar esas dos operaciones, pero no puedo pensar de inmediato en una razón por la que eso es definitivamente incorrecto y, por lo tanto, se requiere este diseño . Es una opción a considerar, ocasionalmente.
En realidad, creo que lo que está más mal con este código es que la pertenencia a la
guests
matriz significa cosas diferentes en diferentes puntos del código. Por lo tanto, ciertamente no lo llamaría un "patrón", pero no sé si es un defecto suficiente para descartar hacer algo de este tipo :-)fuente
Si es posible, debe usar un iterador que atraviese todos los elementos de la matriz. Utiliza la matriz solo como una secuencia, no como almacenamiento de acceso aleatorio, por lo que sería obvio que un iterador que solo hace un acceso secuencial sería más rápido. Imagina que una matriz es en realidad un árbol binario, pero alguien ha escrito un código que determina la "longitud" contando los elementos y el código que accede al elemento i-ésimo, también atravesando el elemento, cada uno en O (n ) Un iterador puede ser muy rápido, su ciclo será muy lento.
fuente