2008-11-04 6 views
19

Sé que en JavaScript, la creación de un bucle for como este: for(int i = 0; i < arr.length; i++) es costoso ya que calcula la longitud de la matriz cada vez. Este comportamiento es costoso en C# para listas y arreglos también. ¿O en tiempo de compilación está optimizado? Además, ¿qué pasa con otros lenguajes como Java, cómo se maneja esto?Es costoso hacer array.length o list.count en un bucle

Respuesta

26

Es no costoso en C#. Por un lado, no hay ningún "cálculo": consultar la longitud es básicamente una operación elemental gracias a la creación de líneas. Y en segundo lugar, debido a que (according to its developers), el compilador reconoce este patrón de acceso y, de hecho, optimizará cualquier control de límites (redundante) para acceder a los elementos de la matriz.

Y, por cierto, creo que algo similar es cierto para las máquinas virtuales JavaScript modernas, y si no lo es, será muy pronto ya que esta es una optimización trivial.

+1

¿Qué es inlinking, inline? – maxfridbe

+0

Es un error tipográfico. ;-) Gracias. –

+0

en cuanto a JavaScript, utiliza la basura "(var i = 0, mi = arr.length; i Sciolist

3

En casi cualquier idioma, la respuesta será "depende".

Principalmente, depende de si el compilador es lo suficientemente inteligente como para saber si la longitud de la lista o la matriz pueden cambiar mientras está en el ciclo.

Sin embargo, es poco probable que esté definido por la especificación del lenguaje.

Por lo tanto, es seguro asumir que la compilación puede no ser capaz de resolver eso. Si realmente cree que la longitud del objeto no cambiará, no dude en calcular la longitud primero y usarla en las construcciones de control de lazo.

Pero cuidado con otros hilos ...

+0

Bueno, para lenguajes como C#, la respuesta definitivamente no es "depende" ya que el comportamiento está bastante bien documentado. –

0

También dependerá de si captador que está haciendo un cálculo, o acceder a un valor conocido.

5
  1. arrays Todo .Net tienen un campo que contiene la longitud de la matriz, por lo que la longitud no se calcula en uso, pero en el momento de la creación.

  2. La máquina virtual .Net es muy buena eliminando cheques de límites siempre que sea posible, este es uno de esos casos donde la verificación de límites se mueve fuera del bucle (en la mayoría de las situaciones, si no son solo 2 instrucciones) .

Editar:

Array Bounds Check Elimination

+0

Perdón por la rez, pero ¿tiene alguna fuente sobre esto? –

+1

@JacobStamm Ver mi edición –

0

creo que si se utiliza el método de extensión LINQ Count(), entonces se puede calcular cada vez que se llama.

+2

No para matrices, no. Para las matrices, 'Count' simplemente llama a la propiedad' Length'. –

+0

En realidad, devuelve 'ICollection.Count' para todas las colecciones que implementan' ICollection'. En matrices, esta propiedad se implementa implícitamente; por lo tanto, no lo verá cuando acceda directamente a la matriz. 'ICollection.Count' simplemente devuelve la propiedad' Length' para matrices. –

Cuestiones relacionadas