La meilleure façon de décider de ce genre de questions est de les évaluer :
use strict;
use warnings;
use Benchmark qw(:all);
our @input_array = (0..1000);
my $a = sub {
my @array = @{[ @input_array ]};
my $index = 0;
foreach my $element (@array) {
die unless $index == $element;
$index++;
}
};
my $b = sub {
my @array = @{[ @input_array ]};
my $index = 0;
while (defined(my $element = shift @array)) {
die unless $index == $element;
$index++;
}
};
my $c = sub {
my @array = @{[ @input_array ]};
my $index = 0;
while (scalar(@array) !=0) {
my $element = shift(@array);
die unless $index == $element;
$index++;
}
};
my $d = sub {
my @array = @{[ @input_array ]};
foreach my $index (0.. $#array) {
my $element = $array[$index];
die unless $index == $element;
}
};
my $e = sub {
my @array = @{[ @input_array ]};
for (my $index = 0; $index <= $#array; $index++) {
my $element = $array[$index];
die unless $index == $element;
}
};
my $f = sub {
my @array = @{[ @input_array ]};
while (my ($index, $element) = each @array) {
die unless $index == $element;
}
};
my $count;
timethese($count, {
'1' => $a,
'2' => $b,
'3' => $c,
'4' => $d,
'5' => $e,
'6' => $f,
});
Et en exécutant ceci sur perl 5, version 24, subversion 1 (v5.24.1) construit pour x86_64-linux-gnu-thread-multi
J'ai compris :
Benchmark: running 1, 2, 3, 4, 5, 6 for at least 3 CPU seconds...
1: 3 wallclock secs ( 3.16 usr + 0.00 sys = 3.16 CPU) @ 12560.13/s (n=39690)
2: 3 wallclock secs ( 3.18 usr + 0.00 sys = 3.18 CPU) @ 7828.30/s (n=24894)
3: 3 wallclock secs ( 3.23 usr + 0.00 sys = 3.23 CPU) @ 6763.47/s (n=21846)
4: 4 wallclock secs ( 3.15 usr + 0.00 sys = 3.15 CPU) @ 9596.83/s (n=30230)
5: 4 wallclock secs ( 3.20 usr + 0.00 sys = 3.20 CPU) @ 6826.88/s (n=21846)
6: 3 wallclock secs ( 3.12 usr + 0.00 sys = 3.12 CPU) @ 5653.53/s (n=17639)
Ainsi, le "foreach (@Array)" est environ deux fois plus rapide que les autres. Tous les autres sont très similaires.
@ikegami souligne également qu'il existe un certain nombre de différences dans ces implémentations autres que la vitesse.
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.
2 votes
Le chapitre 24 de la troisième édition de Programming Perl contient une section sur l'efficacité qu'il est bon de lire. Elle aborde les différents types d'efficacité tels que le temps, le programmeur, le mainteneur. La section commence par l'affirmation suivante : "Notez que l'optimisation du temps peut parfois vous coûter en espace ou en efficacité du programmeur (indiqué par des conseils contradictoires ci-dessous). Ce sont les ruptures".
1 votes
Une seule façon d'additionner deux nombres ? Pas si vous regardez les appels / implémentations de plus bas niveau.... pensez à carry lookahead, aux additionneurs carry save, etc.