Perl est un langage à typage dynamique et à grande flexibilité, ce qui entraîne souvent des coûts de performance implicites lorsqu'il est mal utilisé. L'optimisation des performances est une partie intégrante du support des scripts moyens et grands.
Depuis le début, Perl a été orienté vers la rapidité de prototypage et l'intégration rapide des bibliothèques. La véritable optimisation est apparue des années plus tard, avec l'arrivée de modules de profilage (Devel::DProf, NYTProf), d'analyse des allocations et de l'émergence de meilleures pratiques largement acceptées.
Les principaux goulets d'étranglement proviennent d'une croissance incontrôlée des structures, d'allocations inutiles, de copies fréquentes de données et de caractéristiques de fonctionnement non évidentes de l'interpréteur Perl — par exemple, une utilisation incorrecte des variables globales et des expressions régulières inefficaces.
perl -d:NYTProf script.pl, après quoi les rapports sont analysés via nytprofhtmlundefExemple de code: — comparaison de map en ligne contre une simple boucle :
my @data = (1..1_000_000); my @result = map { $_ * 2 } @data; # potentiellement plus lent pour des calculs complexes # vs my @result; foreach (@data) { push @result, $_ * 2; }
L'utilisation de map est-elle toujours plus rapide que foreach ?
Non. Pour de simples manipulations sur de courts tableaux, il n'y a presque pas de différence, mais les expressions complexes ou le travail avec de grands tableaux peuvent ralentir à cause des listes temporaires de map. Avec foreach, on peut contrôler la mémoire manuellement.
L'autovivification affecte-t-elle les performances ?
Oui, surtout lors de la création aléatoire de grandes structures imbriquées. La création automatique de nouveaux niveaux peut consommer très rapidement de la mémoire si l'on accède accidentellement à un hash non initialisé en profondeur de la structure.
Est-il nécessaire de déclarer les variables avec my à l'avance pour accélérer ?
Oui, mais pas toujours pour des raisons de rapidité — les variables à portée locale sont souvent plus accessibles rapidement par Perl que les globales, cependant, le véritable gain dépend de la taille du programme et du nombre d'accès.
Exemple :
my $sum = 0; foreach my $x (@big_array) { $sum += $x; }
Dans un grand script ETL, les logs sont traités avec map sur des millions d'enregistrements avec des expressions régulières imbriquées. Le script consomme de la mémoire vive et va dans swap après 20 minutes de fonctionnement.
Avantages :
Inconvénients :
Un profilage a été effectué, des boucles explicites ont été ajoutées, les regex ont été décomposées en étapes, tous les grands tableaux ont été convertis en références. Le temps d'exécution du script a été réduit de moitié, la consommation de mémoire a été multipliée par 10.
Avantages :
Inconvénients :