112 votes

Meilleure façon d'itérer dans un tableau Perl

Quelle est la meilleure implémentation (en termes de vitesse et d'utilisation de la mémoire) pour itérer dans un tableau Perl ? Existe-t-il une meilleure méthode ? ( @Array ne doit pas être retenu).

Mise en œuvre 1

foreach (@Array)
{
      SubRoutine($_);
}

Mise en œuvre 2

while($Element=shift(@Array))
{
      SubRoutine($Element);
}

Mise en œuvre 3

while(scalar(@Array) !=0)
{
      $Element=shift(@Array);
      SubRoutine($Element);
}

Mise en œuvre 4

for my $i (0 .. $#Array)
{
      SubRoutine($Array[$i]);
}

Mise en œuvre 5

map { SubRoutine($_) } @Array ;

2 votes

Pourquoi y aurait-il un "meilleur" ? D'autant plus que nous n'avons aucune idée de la manière dont vous pourriez mesurer l'un par rapport à l'autre (la vitesse est-elle plus importante que l'utilisation de la mémoire ? map et réponse acceptable ?. etc.)

2 votes

Deux des trois que vous avez affichés me feraient dire "WTH ?!" à moins qu'il n'y ait un contexte environnant supplémentaire pour en faire des alternatives raisonnables. Dans tous les cas, cette question se situe au niveau de " Quelle est la meilleure façon d'additionner deux nombres ? " La plupart du temps, il n'y a qu'une seule solution. Puis, il y a ces circonstances, où vous avez besoin d'un moyen différent. Vote de clôture.

4 votes

@SinanÜnür Je comprends votre opinion (qu'il n'y a qu'une seule façon d'additionner deux nombres), mais l'analogie n'est pas assez forte pour être utilisée avec dédain. De toute évidence, il y a plus d'une façon de faire, et le PO veut comprendre ce qui est une bonne idée et ce qui ne l'est pas.

2voto

goldilocks Points 6181

Le point 1 est sensiblement différent des points 2 et 3, puisqu'il laisse le tableau intact, alors que les deux autres le laissent vide.

Je dirais que le numéro 3 est assez farfelu et probablement moins efficace, alors oubliez-le.

Il ne reste donc que les numéros 1 et 2, qui ne font pas la même chose, et l'un ne peut donc pas être "meilleur" que l'autre. Si le tableau est grand et que vous n'avez pas besoin de le garder, généralement Le champ d'application s'en occupera ( mais voyez NOTE ), donc généralement Le numéro 1 reste la méthode la plus claire et la plus simple. Décaler chaque élément n'accélérera rien. Même s'il y a un besoin de libérer le tableau de la référence, j'irais simplement :

undef @Array;

une fois terminé.

  • NOTE : La sous-routine contenant la portée du tableau conserve en fait le tableau et réutilise l'espace la prochaine fois. Généralement cela devrait aller (voir les commentaires).

0 votes

@Array = (); ne libère pas le tableau sous-jacent. Même sortir du champ d'application ne le ferait pas. Si vous vouliez libérer le tableau sous-jacent, vous auriez dû utiliser undef @Array; .

2 votes

Démonstration ; 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

0 votes

QUOI ? Je pensais que l'intérêt de la GC était qu'une fois que le nombre de références == 0, la mémoire impliquée devient recyclable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X