Dans mes tests, j'ai remarqué que l'itération des tableaux liés est au mieux moitié aussi rapide que l'utilisation des méthodes d'accesseur interne ( avec une taille de matrice de 1000, le repère de référence: p> J'ai omis les autres courses Parce que la taille de la matrice ne produit pas de changement significatif dans les vitesses relatives. p> Ajout même de la localisation de Quel travail supplémentaire se produit dans la boucle code> pour code> qui ne se produit pas dans Fetch code> et extraire code>). Le repère suivant montre le problème: méthode code> est bien sûr le plus rapide, car il ne vérifie pas la taille de la matrice sur chaque itération, toutefois méthod_while code> et méthody_while2 code> semble fonctionner sur le tableau fixé de la même manière que le pour code> boucle, mais même le code Méthode_whIII2 code> est deux fois plus rapide que la matrice liée. p> $ _ code> et affectation aliasée à méthod_while2 code> dans Méthode_wwile3 code> résulte en 66% d'exécution plus rapide que la matrice liée. p> méthode_while3 < / code>? Y a-t-il un moyen d'améliorer la vitesse de la matrice liée? P> p>
3 Réponses :
Chaque fois que vous utilisez la matrice liée, il doit rechercher l'objet attaché, puis rechercher les méthodes, puis les invoquer. Avec vos autres versions, vous faites tout ou partie de cette recherche soit au moment de la compilation, soit une fois avant la boucle au lieu de chaque accès. P>
(la comparaison des vitesses entre méthode code> et l'autre méthode _ * code> est un bon exemple de ceci, en passant: vous voyez la dépense de le faire extraire code>, même si l'objet attaché a déjà levé les yeux. Maintenant, appliquez maintenant ce coût à chaque opération qui touche le tableau.) P>
Méthode_while3 Code> ne prépache rien et semble faire tout ce que la boucle de foresach est, mais reste 66% plus rapide.
Je pense que cela fait de la mise en cache: avec le code de bouclage explicite, l'optimiseur de Perl peut voir ce qui se passe et même étant donné que le extraire code> ne peut pas être soulevé de la boucle (puisqu'il ne peut pas Dites que vous n'ayez pas accès à une ressource externe dont la taille peut changer de manière dynamique), il peut i> voir que l'appel code> lié i> doit être effectué une seule fois. Je ne pense pas que cela se produise pour pour @ $ array code> car les internes sont cachés à partir de vous et de l'optimiseur. (L'optimisation au Perl 5 est ... difficile, de la mettre légèrement, de sorte que dans de nombreux cas, cela n'essaie même pas.) BTW, il s'agit de la version très perl dépendante.
J'ai remplacé le (@ $ tableau) -> méthode code> avec My $ get_tied = sous {attaché (@ {$ _ [0]})}; code> puis $ get_tied -> ($ array) -> Méthode Code> pour contrecarrer toute sorte de mise en cache et même ajouter ces deux appels de sous-programme supplémentaires à chaque itération est toujours de 25% plus rapide que la boucle code> pour code> :(
Dans la référence, vous faites
tied_rvalue => sub {
my $x = 0;
$x += $_ for @$array;
$x == $sum or die $x
},
tied_lvalue => sub {
my $x = 0;
$x += $array->[$_] for 0 .. $tied->FETCHSIZE - 1;
$x == $sum or die $x
},
100:
Rate tied_rvalue method_while3 tied_lvalue method_while2 method_while method
tied_rvalue 3333/s -- -33% -36% -50% -58% -77%
method_while3 4998/s 50% -- -4% -25% -36% -66%
tied_lvalue 5184/s 56% 4% -- -23% -34% -65%
method_while2 6699/s 101% 34% 29% -- -15% -55%
method_while 7856/s 136% 57% 52% 17% -- -47%
method 14747/s 342% 195% 184% 120% 88% --
+1, intéressant, je n'avais pas envisagé que Perl a besoin d'appliquer la magie à la variable pour gérer un appel possible ultérieur à Store code>
Il est à noter que Même si local code> est très lent qui représente une partie de la perte de performance dans la méthode_while3 vs les autres points de repère de méthode. Il fait également une entrée de bloc et une sortie qui comporte des coûts. P>
Method_while3 code> est équivalent par programmation à la relève pour x..y code>, Perl peut optimiser la boucle mieux que possible. En règle générale, plus vous faites du code à l'intérieur de Perl, plus votre code sera plus rapide. P>
méthode code> serait encore plus rapide si Perl peut optimiserpour 0. y code> en ne construisant pas pré-construire un tableau de longueur Y. L'optimiseur est facilement dupe si y n'est pas un scalaire simple . Essayezma taille $ = $ like-> aller-gretsize - 1; $ x + = $ attaché-> récupérez ($ _) pour 0. $ Taille code> et voyez si cela fonctionne mieux.