¿Cuál es la mejor implementación (en términos de velocidad y uso de memoria) para iterar a través de una matriz Perl? ¿Hay alguna forma mejor? ( @Array
no es necesario conservarlo).
Implementación 1
foreach (@Array)
{
SubRoutine($_);
}
Implementación 2
while($Element=shift(@Array))
{
SubRoutine($Element);
}
Implementación 3
while(scalar(@Array) !=0)
{
$Element=shift(@Array);
SubRoutine($Element);
}
Implementación 4
for my $i (0 .. $#Array)
{
SubRoutine($Array[$i]);
}
Implementación 5
map { SubRoutine($_) } @Array ;
map
una respuesta aceptable?, Etc.)Respuestas:
En términos de velocidad: # 1 y # 4, pero no mucho en la mayoría de los casos.
Podría escribir un punto de referencia para confirmar, pero sospecho que encontrará que el n. ° 1 y el n. ° 4 son un poco más rápidos porque el trabajo de iteración se realiza en C en lugar de Perl, y no se produce una copia innecesaria de los elementos de la matriz. (
$_
tiene el alias del elemento en el n. ° 1, pero el n. ° 2 y el n. ° 3 en realidad copian los escalares de la matriz).El número 5 podría ser similar.
En términos de uso de memoria: todos son iguales excepto el n. ° 5.
for (@a)
tiene una carcasa especial para evitar aplanar la matriz. El ciclo itera sobre los índices de la matriz.En términos de legibilidad: # 1.
En términos de flexibilidad: # 1 / # 4 y # 5.
# 2 no admite elementos falsos. # 2 y # 3 son destructivos.
fuente
my @todo = $root; while (@todo) { my $node = shift; ...; push @todo, ...; ...; }
Si solo te preocupan los elementos de
@Array
, usa:o
Si los índices son importantes, use:
O, a partir de
perl
5.12.1, puede utilizar:Si necesita tanto el elemento como su índice en el cuerpo del ciclo,
Yo esperaríautilizandoeach
ser el más rápido, pero luegorenunciará a la compatibilidad con versiones anteriores a 5.12.1perl
s.Algún otro patrón diferente a estos podría ser apropiado en determinadas circunstancias.
fuente
each
sea el más lento. Hace todo el trabajo de los demás menos un alias, más una asignación de lista, dos copias escalares y dos claros escalares.for
iterar sobre los índices de una matriz, y un 20% más rápido al iterar sobre los índices de una referencia de matriz (accedo$array->[$i]
en el cuerpo), sobre el usoeach
junto conwhile
.En mi opinión, la implementación n. ° 1 es típica y ser breve e idiomático para Perl supera a los demás solo por eso. Un punto de referencia de las tres opciones podría ofrecerle una idea de la velocidad, al menos.
fuente
1 es sustancialmente diferente de 2 y 3, ya que deja la matriz intacta, mientras que los otros dos la dejan vacía.
Yo diría que el número 3 es bastante loco y probablemente menos eficiente, así que olvídalo.
Lo que te deja con el # 1 y el # 2, y no hacen lo mismo, por lo que uno no puede ser "mejor" que el otro. Si la matriz es grande y no necesita conservarla, generalmente el alcance se ocupará de ella ( pero vea la NOTA ), por lo que , en general , el # 1 sigue siendo el método más claro y simple. Desactivar cada elemento no acelerará nada. Incluso si existe la necesidad de liberar la matriz de la referencia, simplemente iría:
cuando termine.
fuente
@Array = ();
no libera la matriz subyacente. Ni siquiera salir del alcance haría eso. Si quisiera liberar la matriz subyacente, tendría usoundef @Array;
.perl -MDevel::Peek -e'my @a; Dump(\@a,1); @a=qw( a b c ); Dump(\@a,1); @a=(); Dump(\@a,1); undef @a; Dump(\@a,1);' 2>&1 | grep ARRAY
()
vsundef
, pero si salir del alcance no libera la memoria utilizada por una matriz local en ese alcance, ¿eso no convierte a Perl en un desastre con fugas? Eso no puede ser verdad.En una sola línea para imprimir el elemento o matriz.
imprimir $ _ para (@array);
NOTA: recuerde que $ _ se refiere internamente al elemento de @array en bucle. Cualquier cambio realizado en $ _ se reflejará en @array; ex.
salida: 2 4 6
fuente
La mejor manera de decidir preguntas como esta para compararlas:
Y ejecutando esto en perl 5, versión 24, subversion 1 (v5.24.1) construido para x86_64-linux-gnu-thread-multi
Yo obtengo:
Entonces, el 'foreach (@Array)' es aproximadamente el doble de rápido que los demás. Todos los demás son muy similares.
@ikegami también señala que hay bastantes diferencias en estas implicaciones además de la velocidad.
fuente
$index < $#array
debería ser en realidad$index <= $#array
porque$#array
no es la longitud de la matriz sino el último índice de la misma.