¿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? ( @Arrayno 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 ;

mapuna 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
perl5.12.1, puede utilizar:Si necesita tanto el elemento como su índice en el cuerpo del ciclo,
Yo esperaríautilizandoeachser el más rápido, pero luegorenunciará a la compatibilidad con versiones anteriores a 5.12.1perls.Algún otro patrón diferente a estos podría ser apropiado en determinadas circunstancias.
fuente
eachsea 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.foriterar 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 usoeachjunto 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 < $#arraydebería ser en realidad$index <= $#arrayporque$#arrayno es la longitud de la matriz sino el último índice de la misma.