Englishfrançaisespagnol

Icône de favori OnWorks

perlperf - En ligne dans le Cloud

Exécutez perlperf dans le fournisseur d'hébergement gratuit OnWorks sur Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS

Il s'agit de la commande perlperf qui peut être exécutée dans le fournisseur d'hébergement gratuit OnWorks en utilisant l'un de nos multiples postes de travail en ligne gratuits tels que Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS

PROGRAMME:

Nom


perlperf - Performances Perl et techniques d'optimisation

DESCRIPTION


Il s'agit d'une introduction à l'utilisation des techniques de performance et d'optimisation qui peuvent être
utilisé avec une référence particulière aux programmes perl. Alors que de nombreux développeurs perl sont venus
d'autres langues et peuvent utiliser leurs connaissances antérieures le cas échéant, il existe de nombreux
d'autres personnes qui pourraient bénéficier de quelques pointeurs spécifiques à Perl. Si vous voulez le
version condensée, le meilleur conseil vient peut-être du célèbre samouraï japonais,
Miyamoto Musashi, qui a dit :

"Ne vous engagez pas dans des activités inutiles"

en 1645

APERÇU


L'erreur la plus courante des programmeurs est peut-être d'essayer d'optimiser leur code
avant qu'un programme ne fasse quoi que ce soit d'utile - c'est une mauvaise idée. Il ne sert à rien
avoir un programme extrêmement rapide qui ne fonctionne pas. Le premier travail consiste à obtenir un programme pour
correctement faire quelque chose incontournable, (sans parler de s'assurer que la suite de tests est entièrement
fonctionnel), et alors seulement d'envisager de l'optimiser. Ayant décidé d'optimiser l'existant
code de travail, il y a plusieurs étapes simples mais essentielles à considérer qui sont intrinsèques
à tout processus d'optimisation.

ONE ÉTAPE DE CÔTÉ
Tout d'abord, vous devez établir un temps de référence pour le code existant, dont le temps a besoin
être fiable et reproductible. Vous voudrez probablement utiliser le « Benchmark » ou
Modules "Devel::NYTProf", ou quelque chose de similaire, pour cette étape, ou peut-être le système Unix
l'utilitaire "time", selon ce qui est approprié. Voir la base de ce document pour une liste plus longue
des modules d'analyse comparative et de profilage, et des lectures supplémentaires recommandées.

ONE ÉTAPE AVANT
Ensuite, après avoir examiné le programme de chaudes taches, (endroits où le code semble s'exécuter
lentement), modifiez le code dans le but de le faire s'exécuter plus rapidement. Utilisation de la version
un logiciel de contrôle, comme "subversion", garantira qu'aucun changement n'est irréversible. C'est trop
facile à jouer ici et là-bas - ne changez pas trop à la fois ou vous pourriez
pas découvrir quel morceau de code vraiment était le peu lent.

UN AUTRE ÉTAPE DE CÔTÉ
Il ne suffit pas de dire : "ça va le faire tourner plus vite", il faut le vérifier. Réexécutez le
code sous contrôle des modules de benchmarking ou de profilage, dès la première étape ci-dessus,
et vérifiez que le nouveau code a exécuté le même tâche in moins fois. Enregistrez votre travail et
répéter...

GÉNÉRAL LIGNES DIRECTRICES


L'essentiel lorsque l'on considère les performances est de se rappeler qu'il n'y a pas de
"Golden Bullet", c'est pourquoi il n'y a pas de règles, seulement des lignes directrices.

Il est clair que le code en ligne sera plus rapide que les appels de sous-programmes ou de méthodes,
car il y a moins de frais généraux, mais cette approche a l'inconvénient d'être moins
maintenable et se fait au prix d'une plus grande utilisation de la mémoire - il n'y a pas de
repas gratuit. Si vous recherchez un élément dans une liste, il peut être plus efficace de
stockez les données dans une structure de hachage, puis regardez simplement si la clé est
défini, plutôt que de parcourir tout le tableau en utilisant grep() par exemple. substr ()
peut être (beaucoup) plus rapide que grep() mais pas aussi flexible, vous avez donc un autre compromis à faire
accès. Votre code peut contenir une ligne qui prend 0.01 seconde à s'exécuter qui si vous
appelez-le 1,000 XNUMX fois, très probablement dans un programme analysant même des fichiers de taille moyenne pour
exemple, vous avez déjà un délai de 10 secondes, dans un seul emplacement de code, et si vous
appelez cette ligne 100,000 XNUMX fois, tout votre programme ralentira à un rythme insupportable.

L'utilisation d'un sous-programme dans le cadre de votre tri est un moyen puissant d'obtenir exactement ce que vous voulez,
mais sera généralement plus lent que le intégré alphabétique "cmp" et numérique Trier "<=>"
les opérateurs. Il est possible de faire plusieurs passages sur vos données, en construisant des indices pour
rendre le tri à venir plus efficace, et d'utiliser ce qu'on appelle le « OM » (orc
Manœuvre) pour mettre en cache les clés de tri à l'avance. La recherche dans le cache, bien qu'elle soit une bonne idée, peut
être lui-même une source de ralentissement en imposant un double passage sur les données - une fois à paramétrer
le cache, et une fois pour trier les données. Utilisation de "pack()" pour extraire la clé de tri requise
dans une chaîne cohérente peut être un moyen efficace de créer une seule chaîne à comparer,
au lieu d'utiliser plusieurs clés de tri, ce qui permet d'utiliser le standard, écrit
en "c" et rapide, perl fonction "sort()" sur la sortie, et est la base du "GRT"
(Transformation de Guttman Rossler). Certaines combinaisons de cordes peuvent ralentir le "GRT", en
étant trop simple et complexe pour son propre bien.

Pour les applications utilisant des backends de base de données, l'espace de noms standard "DBIx" a essayé d'aider
en gardant les choses serrées, notamment parce qu'il essaie de pas interroger la base de données jusqu'à ce que le
dernier moment possible, mais lisez toujours les documents qui accompagnent votre choix de bibliothèques.
Parmi les nombreux problèmes auxquels les développeurs qui s'occupent des bases de données doivent rester conscients, il y a
de toujours utiliser des espaces réservés "SQL" et d'envisager de pré-extraire des ensembles de données lorsque cela pourrait
s'avérer avantageux. Fractionnement d'un fichier volumineux en attribuant plusieurs processus à l'analyse
un seul fichier, en utilisant par exemple "POE", "threads" ou "fork" peut également être un moyen utile d'optimiser
votre utilisation des ressources "CPU" disponibles, bien que cette technique soit lourde de
problèmes de concurrence et exige une grande attention aux détails.

Chaque cas a une application spécifique et une ou plusieurs exceptions, et il n'y a pas de
remplacement pour exécuter quelques tests et découvrir quelle méthode fonctionne le mieux pour votre
environnement particulier, c'est pourquoi écrire du code optimal n'est pas une science exacte, et pourquoi
nous aimons tellement utiliser Perl - TMTOWTDI.

REPÈRES


Voici quelques exemples pour illustrer l'utilisation des outils d'analyse comparative de Perl.

Attribution et Déréférencement Variables
Je suis sûr que la plupart d'entre nous ont vu du code qui ressemble (ou pire que) à ceci :

if ( $obj->{_ref}->{_myscore} >= $obj->{_ref}->{_yourscore} ) {


Ce genre de code peut être une vraie horreur à lire, en plus d'être très sensible aux fautes de frappe,
et il est beaucoup plus clair de déréférencer la variable explicitement. Nous évitons le
problème de travailler avec des techniques de programmation orientées objet pour encapsuler des variables
accès via des méthodes, accessible uniquement via un objet. Ici, nous ne parlons que de
mise en œuvre technique de choix, et si cela a un effet sur les performances. Nous pouvons
voir si cette opération de déréférencement a un surcoût en mettant du code comparatif dans
un fichier et en exécutant un test "Benchmark".

# déréférencement

#!/usr/bin/perl

utiliser strict;
utiliser des avertissements ;

utiliser Benchmark ;

ma $ref = {
'ref' => {
_myscore => '100 + 1',
_yourscore => '102 - 1',
},
};

foisces(1000000, {
'direct' => sous {
mon $x = $ref->{ref}->{_myscore} . $ref->{ref}->{_yourscore} ;
},
'déréférencement' => sous {
mon $ref = $ref->{ref} ;
mon $monscore = $ref->{_myscore} ;
mon $yourscore = $ref->{_yourscore} ;
mon $x = $monscore . $votrenote ;
},
});

Il est essentiel d'exécuter toutes les mesures de synchronisation un nombre suffisant de fois pour que les nombres
s'installer sur une moyenne numérique, sinon chaque exécution fluctuera naturellement en raison de
variations de l'environnement, pour réduire l'effet de contention pour les ressources "CPU" et
bande passante du réseau par exemple. En exécutant le code ci-dessus pour un million d'itérations, nous pouvons
jetez un œil au rapport produit par le module « Benchmark », pour voir quelle approche est la
le plus efficace.

$> déréférencement perl

Benchmark : timing 1000000 itérations de déréférencement, direct...
déréférencement : 2 secondes d'horloge murale (1.59 usr + 0.00 sys = 1.59 CPU) à 628930.82/s (n=1000000)
direct : 1 seconde d'horloge murale (1.20 usr + 0.00 sys = 1.20 CPU) à 833333.33/s (n=1000000)

La différence est nette et la démarche de déréférencement est plus lente. Alors qu'il a réussi
exécuter en moyenne 628,930 XNUMX fois par seconde lors de notre test, l'approche directe
réussi à exécuter 204,403 XNUMX fois supplémentaires, malheureusement. Malheureusement, parce qu'il y
sont de nombreux exemples de code écrit en utilisant l'accès variable direct à plusieurs couches, et
c'est généralement horrible. Il est cependant moins rapide. La question demeure de savoir si
le gain infime vaut en fait la fatigue oculaire ou la perte de maintenabilité.

Rechercher et remplacer or tr
Si nous avons une chaîne qui doit être modifiée, alors qu'une expression régulière sera presque toujours beaucoup
plus flexible, "tr", un outil souvent sous-utilisé, peut toujours être utile. Un scénario pourrait être
remplacer toutes les voyelles par un autre caractère. La solution regex pourrait ressembler à ceci :

$str =~ s/[aeiou]/x/g

L'alternative "tr" pourrait ressembler à ceci :

$str =~ tr/aeiou//

Nous pouvons mettre cela dans un fichier de test que nous pouvons exécuter pour vérifier quelle approche est la plus rapide,
utiliser une variable globale $STR à affecter à la variable "my $str" afin d'éviter perl
essayer d'optimiser le travail en remarquant qu'il n'est attribué qu'une seule fois.

# regex-translittération

#!/usr/bin/perl

utiliser strict;
utiliser des avertissements ;

utiliser Benchmark ;

my $STR = "$$-ceci et cela" ;

foisces( 1000000, {
'sr' => sub { ma $str = $STR; $str =~ s/[aeiou]/x/g; renvoie $str; },
'tr' => sub { my $str = $STR; $str =~ tr/aeiou//; retourne $str ; },
});

L'exécution du code nous donne nos résultats :

$> perl regex-transliterate

Benchmark : timing 1000000 itérations de sr, tr...
sr : 2 secondes d'horloge murale (1.19 usr + 0.00 sys = 1.19 CPU) @ 840336.13/s (n=1000000)
tr : 0 s d'horloge murale (0.49 usr + 0.00 sys = 0.49 CPU) @ 2040816.33/s (n=1000000)

La version "tr" est clairement gagnante. Une solution est flexible, l'autre est rapide - et
c'est le choix du programmeur qui doit l'utiliser.

Consultez la documentation "Benchmark" pour d'autres techniques utiles.

PROFILAGE OUTILS


Un morceau de code légèrement plus gros fournira quelque chose sur lequel un profileur peut produire
des statistiques de déclaration plus complètes. Cet exemple utilise le programme simpliste "wordmatch"
qui analyse un fichier d'entrée donné et crache un bref rapport sur le contenu.

# correspondance de mots

#!/usr/bin/perl

utiliser strict;
utiliser des avertissements ;

=head1 NOM

filewords - analyse des mots du fichier d'entrée

=head1 RÉSUMÉ

mots de fichier -f nomfichier d'entrée [-d]

=tête1 DESCRIPTION

Ce programme analyse le nom de fichier donné, spécifié avec C<-f>, et affiche un
simple analyse des mots qui s'y trouvent. Utilisez le commutateur C<-d> pour activer
messages de débogage.

=couper

utiliser FileHandle ;
utilisez Getopt::Long;

mon $debug = 0 ;
mon $fichier = '';

mon $result = GetOptions (
'debug' => \$debug,
'fichier=s' => \$fichier,
);
die("arguments invalides") sauf si $result ;

à moins que ( -f $file ) {
die("Utilisation : $0 -f nom de fichier [-d]");
}
my $FH = FileHandle->new("< $file") ou die("unable to open file($file): $!");

mes $i_LINES = 0 ;
mes $i_WORDS = 0 ;
mon %count = ();

mes @lignes = <$FH> ;
foreach ma $line ( @lines ) {
$i_LINES++ ;
$ligne =~ s/\n//;
mes @mots = split(/ +/, $line);
mes $i_words = scalaire(@mots);
$i_WORDS = $i_WORDS + $i_words ;
debug("ligne : $i_LINES fournissant des mots $i_words : @words");
mon $i_word = 0 ;
foreach mon $mot ( @mots ) {
$i_mot++ ;
$count{$i_LINES}{spec} += matches($i_word, $word, '[^a-zA-Z0-9]');
$count{$i_LINES}{uniquement} += matchs($i_word, $word, '^[^a-zA-Z0-9]+$');
$count{$i_LINES}{cons} += matches($i_word, $word, '^[(?i:bcdfghjklmnpqrstvwxyz)]+$');
$count{$i_LINES}{vœux} += matches($i_word, $word, '^[(?i:aeiou)]+$');
$count{$i_LINES}{caps} += matches($i_word, $word, '^[(AZ)]+$');
}
}

imprimer le rapport( %count );

sous-correspondance {
mon $i_wd = décalage ;
mon $word = shift;
mon $regex = décalage ;
mon $ a = 0 ;

si ( $mot =~ /($regex)/ ) {
$ha++ si $1;
}

debug("mot : $i_wd ".($a ? 'correspond à' : 'ne correspond pas')." chars: /$regex/");

renvoie $has ;
}

sous-rapport {
mon %rapport = @_;
mon %rep;

foreach my $line ( clés %report ) {
foreach ma $key ( keys %{ $report{$line} } ) {
$rep{$key} += $report{$line}{$key} ;
}
}

mon $rapport = qq|
0 $ rapport pour $file :
lignes dans le fichier : $i_LINES
mots dans le fichier : $i_WORDS
mots avec des caractères spéciaux (non-mots) : $i_spec
mots avec uniquement des caractères spéciaux (non-mots) : $i_only
mots avec seulement des consonnes : $i_cons
mots avec seulement des majuscules : $i_caps
mots avec seulement des voyelles : $i_vows
|;

renvoie $rapport ;
}

sous-débogage {
mon $message = shift;

si ( $debug ) {
print STDERR "DBG : $message\n" ;
}
}

sortie 0 ;

Développeur ::DProf
Ce module vénérable est la norme de facto pour le profilage de code Perl depuis plus de
une décennie, mais a été remplacé par un certain nombre d'autres modules qui nous ont ramenés à
le 21ème siècle. Bien qu'il vous soit recommandé d'évaluer votre outil à partir de plusieurs
mentionné ici et de la liste CPAN à la base de ce document, (et actuellement
Devel::NYTProf semble être l'arme de choix - voir ci-dessous), nous allons jeter un coup d'œil à
la sortie de Devel::DProf d'abord, pour définir une ligne de base pour les outils de profilage Perl. Exécutez le
programme ci-dessus sous le contrôle de "Devel::DProf" en utilisant le commutateur "-d" sur la commande-
ligne.

$> perl -d:DProf wordmatch -f perl5db.pl

<...plusieurs lignes coupées...>

rapport de correspondance de mots pour perl5db.pl :
lignes dans le fichier : 9428
mots dans le fichier : 50243
mots avec des caractères spéciaux (non-mots): 20480
mots avec uniquement des caractères spéciaux (non-mots): 7790
mots avec seulement des consonnes : 4801
mots avec seulement des majuscules : 1316
mots avec seulement des voyelles : 1701

"Devel::DProf" produit un fichier spécial, appelé tmon.out par défaut, et ce fichier est lu
par le programme "dprofpp", qui est déjà installé dans le cadre du "Devel::DProf"
Distribution. Si vous appelez "dprofpp" sans options, il lira le tmon.out fichier dans
le répertoire actuel et produire un rapport statistique lisible par l'homme de l'exécution de votre
programme. Notez que cela peut prendre un peu de temps.

$> dprofpp

Temps total écoulé = 2.951677 seconde
Utilisateur + Temps système = 2.871677 secondes
Horaires exclusifs
%Time ExclSec CumulS #Appels sec/appel Csec/c Nom
102. 2.945 3.003 251215 0.0000 0.0000 principal::matchs
2.40 0.069 0.069 260643 0.0000 0.0000 main::debug
1.74 0.050 0.050 1 0.0500 0.0500 principal::rapport
1.04 0.030 0.049 4 0.0075 0.0123 principal::DEBUT
0.35 0.010 0.010 3 0.0033 0.0033 Exportateur::as_heavy
0.35 0.010 0.010 7 0.0014 0.0014 IO::File::BEGIN
0.00 - -0.000 1 - - Getopt::Long::FindOption
0.00 - -0.000 1 - - Symbole::DEBUT
0.00 - -0.000 1 - - Fcntl::BEGIN
0.00 - -0.000 1 - - Fcntl::bootstrap
0.00 - -0.000 1 - - avertissements::BEGIN
0.00 - -0.000 1 - - IO::bootstrap
0.00 - -0.000 1 - - Getopt::Long::ConfigDefaults
0.00 - -0.000 1 - - Getopt::Long::Configure
0.00 - -0.000 1 - - Symbole::gensym

"dprofpp" produira des rapports assez détaillés sur l'activité du "wordmatch"
programme. L'horloge murale, l'utilisateur et le système, les heures sont au sommet de l'analyse, et après
ce sont les principales colonnes définissant qui définissent le rapport. Consultez la doc "dprofpp" pour
détails des nombreuses options qu'il prend en charge.

Voir aussi "Apache::DProf" qui accroche "Devel::DProf" dans "mod_perl".

Développeur ::Profiler
Regardons le même programme en utilisant un profileur différent : "Devel::Profiler", un
remplacement de Perl uniquement pour "Devel::DProf". L'utilisation est très légèrement différente dans
qu'au lieu d'utiliser le drapeau spécial "-d:", vous tirez "Devel::Profiler" directement en tant que
module en utilisant "-M".

$> perl -MDevel::Profiler wordmatch -f perl5db.pl

<...plusieurs lignes coupées...>

rapport de correspondance de mots pour perl5db.pl :
lignes dans le fichier : 9428
mots dans le fichier : 50243
mots avec des caractères spéciaux (non-mots): 20480
mots avec uniquement des caractères spéciaux (non-mots): 7790
mots avec seulement des consonnes : 4801
mots avec seulement des majuscules : 1316
mots avec seulement des voyelles : 1701

"Devel::Profiler" génère un fichier tmon.out compatible avec le "dprofpp"
programme, économisant ainsi la construction d'un programme de lecture de statistiques dédié. "dprofpp"
l'utilisation est donc identique à l'exemple ci-dessus.

$> dprofpp

Temps total écoulé = 20.984 seconde
Utilisateur + Temps système = 19.981 secondes
Horaires exclusifs
%Time ExclSec CumulS #Appels sec/appel Csec/c Nom
49.0 9.792 14.509 251215 0.0000 0.0001 principal::correspondance
24.4 4.887 4.887 260643 0.0000 0.0000 main::debug
0.25 0.049 0.049 1 0.0490 0.0490 principal::rapport
0.00 0.000 0.000 1 0.0000 0.0000 Getopt::Long::GetOptions
0.00 0.000 0.000 2 0.0000 0.0000 Getopt::Long::ParseOptionSpec
0.00 0.000 0.000 1 0.0000 0.0000 Getopt::Long::FindOption
0.00 0.000 0.000 1 0.0000 0.0000 IO::Fichier::nouveau
0.00 0.000 0.000 1 0.0000 0.0000 IO::Poignée::nouveau
0.00 0.000 0.000 1 0.0000 0.0000 Symbole::gensym
0.00 0.000 0.000 1 0.0000 0.0000 IO::File::open

Il est intéressant de noter que nous obtenons des résultats légèrement différents, principalement parce que l'algorithme
qui génère le rapport est différent, même si le format du fichier de sortie était prétendument
identique. Les temps écoulés, utilisateur et système indiquent clairement le temps qu'il a fallu pour
"Devel::Profiler" pour exécuter sa propre exécution, mais les listes de colonnes semblent plus précises
en quelque sorte que ceux que nous avions précédemment dans "Devel::DProf". Le chiffre de 102 % a
disparu, par exemple. C'est là que nous devons utiliser les outils à notre disposition, et
reconnaître leurs avantages et leurs inconvénients avant de les utiliser. Fait intéressant, le nombre d'appels à
chaque sous-routine est identique dans les deux rapports, ce sont les pourcentages qui diffèrent. Comme
l'auteur de "Devel::Proviler" écrit :

... l'exécution de la suite de tests de HTML::Template sous Devel::DProf affiche output()
cela ne prend PAS de temps mais Devel::Profiler montre qu'environ 10 % du temps est en sortie().
Je ne sais pas à qui faire confiance mais mon instinct me dit que quelque chose ne va pas
Devel::DProf. HTML::Template::output() est une grande routine qui est appelée pour
chaque essai. Quoi qu'il en soit, quelque chose doit être réparé.

YMMV.

Voir aussi "Devel::Apache::Profiler" qui accroche "Devel::Profiler" à "mod_perl".

Développeur ::SmallProf
Le profileur "Devel::SmallProf" examine le runtime de votre programme Perl et produit un
liste ligne par ligne pour montrer combien de fois chaque ligne a été appelée et combien de temps chaque ligne
pris à exécuter. Il est appelé en fournissant le drapeau "-d" familier à Perl lors de l'exécution.

$> perl -d:SmallProf wordmatch -f perl5db.pl

<...plusieurs lignes coupées...>

rapport de correspondance de mots pour perl5db.pl :
lignes dans le fichier : 9428
mots dans le fichier : 50243
mots avec des caractères spéciaux (non-mots): 20480
mots avec uniquement des caractères spéciaux (non-mots): 7790
mots avec seulement des consonnes : 4801
mots avec seulement des majuscules : 1316
mots avec seulement des voyelles : 1701

"Devel::SmallProf" écrit sa sortie dans un fichier appelé petitprof.out, par défaut. le
le format du fichier ressemble à ceci :

:

Lorsque le programme est terminé, la sortie peut être examinée et triée en utilisant n'importe quel standard
utilitaires de filtrage de texte. Quelque chose comme ce qui suit peut suffire :

$> chat smallprof.out | grep \d* : | trier -k3 | tac | tête -n20

251215 1.65674 7.68000 75 : si ( $word =~ /($regex)/ ) {
251215 0.03264 4.40000 79: debug("word: $i_wd ".($has ? 'matches' :
251215 0.02693 4.10000 81 : renvoie $has ;
260643 0.02841 4.07000 128 : si ( $debug ) {
260643 0.02601 4.04000 126 : mon $message = décalage ;
251215 0.02641 3.91000 73 : mes $ a = 0 ;
251215 0.03311 3.71000 70 : mon $i_wd = décalage ;
251215 0.02699 3.69000 72 : mon $regex = décalage ;
251215 0.02766 3.68000 71 : mon $word = décalage ;
50243 0.59726 1.00000 59 : $count{$i_LINES}{cons} =
50243 0.48175 0.92000 61 : $count{$i_LINES}{spec} =
50243 0.00644 0.89000 56 : mes $i_cons = matches($i_word, $word,
50243 0.48837 0.88000 63 : $count{$i_LINES}{caps} =
50243 0.00516 0.88000 58 : mes $i_caps = matches($i_word, $word, '^[(A-
50243 0.00631 0.81000 54 : mon $i_spec = matches($i_word, $word, '[^a-
50243 0.00496 0.80000 57 : mes $i_vows = matches($i_word, $word,
50243 0.00688 0.80000 53 : $i_word++ ;
50243 0.48469 0.79000 62 : $count{$i_LINES}{uniquement} =
50243 0.48928 0.77000 60 : $compte{$i_LINES}{vœux} =

50243 0.00683 0.75000 55 : mon $i_only = matches($i_word, $word, '^[^a-
Vous pouvez immédiatement voir une focalisation légèrement différente sur les modules de profilage de sous-programmes,
et nous commençons à voir exactement quelle ligne de code prend le plus de temps. Cette ligne d'expression régulière
semble un peu suspect, par exemple. N'oubliez pas que ces outils sont censés être
utilisés ensemble, il n'y a pas de meilleure façon de profiler votre code, vous devez utiliser le meilleur
outils pour le travail.

Voir aussi "Apache::SmallProf" qui accroche "Devel::SmallProf" à "mod_perl".

Développeur ::FastProf
"Devel::FastProf" est un autre profileur de ligne Perl. Ceci a été écrit dans le but d'obtenir
un profileur de ligne plus rapide que ce qui est possible avec par exemple "Devel::SmallProf", car c'est
écrit en "C". Pour utiliser "Devel::FastProf", fournissez l'argument "-d" à Perl :

$> perl -d: correspondance de mots FastProf -f perl5db.pl

<...plusieurs lignes coupées...>

rapport de correspondance de mots pour perl5db.pl :
lignes dans le fichier : 9428
mots dans le fichier : 50243
mots avec des caractères spéciaux (non-mots): 20480
mots avec uniquement des caractères spéciaux (non-mots): 7790
mots avec seulement des consonnes : 4801
mots avec seulement des majuscules : 1316
mots avec seulement des voyelles : 1701

"Devel::FastProf" écrit les statistiques dans le fichier fastprof.out dans le répertoire courant.
Le fichier de sortie, qui peut être spécifié, peut être interprété en utilisant le "fprofpp"
programme en ligne de commande.

$> fprofpp | tête -n20

# le format de sortie de fprofpp est :
# nom de fichier : nombre de lignes : source
correspondance de mots:75 3.93338 251215: if ( $word =~ /($regex)/ ) {
wordmatch:79 1.77774 251215: debug("word: $i_wd ".($has ? 'matches' : 'ne correspond pas')." chars: /$regex/");
correspondance de mots : 81 1.47604 251215 : renvoie $has ;
correspondance de mots:126 1.43441 260643 : mon $message = shift ;
correspondance de mots:128 1.42156 260643: if ( $debug ) {
correspondance de mots : 70 1.36824 251215 : mon $i_wd = décalage ;
correspondance de mots : 71 1.36739 251215 : mon $mot = shift ;
correspondance de mots : 72 1.35939 251215 : mon $regex = décalage ;

On voit d'emblée que le nombre d'appels de chaque ligne est identique à
la sortie "Devel::SmallProf", et la séquence n'est que très légèrement différente en fonction de
l'ordre du temps d'exécution de chaque ligne, "if ( $debug ) { " et " my
$message = shift;", par exemple. Les différences dans les heures réelles enregistrées peuvent être dans
l'algorithme utilisé en interne, ou cela peut être dû à des limitations de ressources système ou
contention.

Voir aussi le DBIx::Profile qui profilera les requêtes de base de données exécutées sous le "DBIx::*"
espace de noms.

Développeur ::NYTProf
"Devel::NYTProf" est le next génération du profileur de code Perl, corrigeant de nombreuses lacunes dans
d'autres outils et la mise en œuvre de nombreuses fonctionnalités intéressantes. Tout d'abord, il peut être utilisé soit comme un
en ligne profileur, un bloc ou sous-programme profileur, tout à la fois. Il peut également utiliser des sous-
résolution de la microseconde (100 ns) sur les systèmes qui fournissent "clock_gettime()". Ça peut être
démarré et arrêté même par le programme en cours de profilage. C'est une entrée d'une ligne pour profiler
applications "mod_perl". Il est écrit en "c" et est probablement le profileur le plus rapide
disponible pour Perl. La liste de la fraîcheur ne fait que s'allonger. Assez de cela, voyons comment
cela fonctionne - utilisez simplement le commutateur "-d" familier pour le brancher et exécuter le code.

$> perl -d:NYTProf wordmatch -f perl5db.pl

rapport de correspondance de mots pour perl5db.pl :
lignes dans le fichier : 9427
mots dans le fichier : 50243
mots avec des caractères spéciaux (non-mots): 20480
mots avec uniquement des caractères spéciaux (non-mots): 7790
mots avec seulement des consonnes : 4801
mots avec seulement des majuscules : 1316
mots avec seulement des voyelles : 1701

"NYTProf" générera une base de données de rapports dans le fichier nytprof.out par défaut. Humain
des rapports lisibles peuvent être générés à partir d'ici en utilisant le "nytprofhtml" fourni (HTML
sortie) et "nytprofcsv" (sortie CSV). Nous avons utilisé le système Unix "html2text"
utilitaire pour convertir le nytprof/index.html fichier pour plus de commodité ici.

$> html2text nytprof/index.html

Indice de profil de performance
Pour la correspondance de mots
Exécuté le vendredi 26 septembre 13:46:39 2008
Signalé le ven. 26 sept. 13:47:23 2008

Top 15 des sous-programmes - classés par heure exclusive
|Appels |P |F |Inclus|Exclusif|Sous-programme |
| | | |Heure |Heure | |
|251215|5 |1 |13.09263 |10.47692 |principal:: |matchs |
|260642|2 |1 |2.71199 |2.71199 |principal :: |débogage |
|1 |1 |1 |0.21404 |0.21404 |principal:: |rapport |
|2 |2 |2 |0.00511 |0.00511 |XSLoader :: |load (xsub) |
|14 |14|7 |0.00304 |0.00298 |Exportateur :: |importer |
|3 |1 |1 |0.00265 |0.00254 |Exportateur :: |as_heavy |
|10 |10|4 |0.00140 |0.00140 |vars :: |importation |
|13 |13|1 |0.00129 |0.00109 |constante :: |importation |
|1 |1 |1 |0.00360 |0.00096 |FileHandle:: |import |
|3 |3 |3 |0.00086 |0.00074 |avertissements::register::|import |
|9 |3 |1 |0.00036 |0.00036 |strict:: |bits |
|13 |13|13|0.00032 |0.00029 |strict:: |import |
|2 |2 |2 |0.00020 |0.00020 |avertissements:: |import |
|2 |1 |1 |0.00020 |0.00020 |Getopt::Long :: |ParseOptionSpec|
|7 |7 |6 |0.00043 |0.00020 |strict:: |unimport |

Pour plus d'informations, consultez la liste complète des 189 sous-programmes.

La première partie du rapport montre déjà les informations critiques sur lesquelles
les sous-routines utilisent le plus de temps. Le suivant donne quelques statistiques sur la source
fichiers profilés.

Fichiers de code source -- classés par heure exclusive puis par nom
|Stmts |Exclusif|Moy. |Rapports |Fichier source |
| |Temps | | | |
|2699761|15.66654 |6e-06 |ligne . bloquer . sous|correspondance de mots |
|35 |0.02187 |0.00062|ligne . bloquer . sub|IO/Handle.pm |
|274 |0.01525 |0.00006|ligne . bloquer . sub|Getopt/Long.pm |
|20 |0.00585 |0.00029|ligne . bloquer . sub|Fcntl.pm |
|128 |0.00340 |0.00003|ligne . bloquer . sub|Exportateur/Heavy.pm |
|42 |0.00332 |0.00008|ligne . bloquer . sous|IO/Fichier.pm |
|261 |0.00308 |0.00001|ligne . bloquer . sous|Exportateur.pm |
|323 |0.00248 |8e-06 |ligne . bloquer . sub|constante.pm |
|12 |0.00246 |0.00021|ligne . bloquer . sous|Fichier/Spéc./Unix.pm |
|191 |0.00240 |0.00001|ligne . bloquer . sous|vars.pm |
|77 |0.00201 |0.00003|ligne . bloquer . sous|FileHandle.pm |
|12 |0.00198 |0.00016|ligne . bloquer . sous|Carpe.pm |
|14 |0.00175 |0.00013|ligne . bloquer . sous|Symbole.pm |
|15 |0.00130 |0.00009|ligne . bloquer . sous|IO.pm |
|22 |0.00120 |0.00005|ligne . bloquer . sub|IO/Seekable.pm |
|198 |0.00085 |4e-06 |ligne . bloquer . sous|avertissements/registre.pm|
|114 |0.00080 |7e-06 |ligne . bloquer . sub|strict.pm |
|47 |0.00068 |0.00001|ligne . bloquer . sous|avertissements.pm |
|27 |0.00054 |0.00002|ligne . bloquer . sous|surcharge.pm |
|9 |0.00047 |0.00005|ligne . bloquer . sub|SelectSaver.pm |
|13 |0.00045 |0.00003|ligne . bloquer . sous|Fichier/Spéc.pm |
|2701595|15.73869 | |Total |
|128647 |0.74946 | |Moyenne |
| |0.00201 |0.00003|Médiane |
| |0.00121 |0.00003|Déviation |

Rapport produit par le profileur NYTProf 2.03 Perl, développé par Tim Bunce et
Adam Kaplan.

À ce stade, si vous utilisez le html rapport, vous pouvez cliquer sur les différents liens pour
dans chaque sous-programme et chaque ligne de code. Parce que nous utilisons le texte
rapports ici, et il y a tout un répertoire plein de rapports construits pour chaque fichier source,
nous afficherons juste une partie du correspondant wordmatch-ligne.html fichier, suffisant pour
donner une idée du type de sortie que vous pouvez attendre de cet outil génial.

$> html2text nytprof/wordmatch-line.html

Profil de performance -- -vue de bloc-.-vue de ligne-.-vue de sous-
Pour la correspondance de mots
Exécuté le vendredi 26 septembre 13:46:39 2008
Signalé le ven. 26 sept. 13:47:22 2008

Fichier de correspondance de mots

Sous-programmes -- classés par heure exclusive
|Appels |P|F|Inclus|Exclusif|Sous-programme |
| | | |Heure |Heure | |
|251215|5|1|13.09263 |10.47692 |main::|matches|
|260642|2|1|2.71199 |2.71199 |principal::|débogage |
|1 |1|1|0.21404 |0.21404 |principal::|rapport |
|0 |0|0|0 |0 |principal::|DEBUT |

|Ligne|Stmts.|Exclusif|Moy. |Code |
| | |Temps | | |
|1 | | | |#!/usr/bin/perl |
|2 | | | | |
| | | | |utiliser strict; |
|3 |3 |0.00086 |0.00029|# passé 0.00003s à faire 1 appels à strict :: |
| | | | |importer |
| | | | |utiliser des avertissements ; |
|4 |3 |0.01563 |0.00521|# a passé 0.00012s à faire 1 appels aux avertissements :: |
| | | | |importer |
|5 | | | | |
|6 | | | |=head1 NOM |
|7 | | | | |
|8 | | | |filewords - analyse des mots du fichier d'entrée |
<...couper...>
|62 |1 |0.00445 |0.00445|imprimer le rapport( %count ); |
| | | | |# a passé 0.21404s à faire 1 appels à main::report|
|63 | | | | |
| | | | |# dépensé 23.56955s (10.47692+2.61571) dans |
| | | | |main::matches qui a été appelé 251215 fois, |
| | | | |moy 0.00005s/appel : # 50243 fois |
| | | | |(2.12134+0.51939s) à la ligne 57 de wordmatch, avg|
| | | | |0.00005s/appel # 50243 fois (2.17735+0.54550s) |
|64 | | | |à la ligne 56 de wordmatch, en moyenne 0.00005s/appel # |
| | | | |50243 fois (2.10992+0.51797s) à la ligne 58 de |
| | | | |match de mots, en moyenne 0.00005s/appel # 50243 fois |
| | | | |(2.12696+0.51598s) à la ligne 55 de wordmatch, avg|
| | | | |0.00005s/appel # 50243 fois (1.94134+0.51687s) |
| | | | |à la ligne 54 de wordmatch, en moyenne 0.00005s/appel |
| | | | |sub correspond { |
<...couper...>
|102 | | | | |
| | | | |# a passé 2.71199s dans main::debug qui était |
| | | | |appelé 260642 fois, en moyenne 0.00001s/appel : # |
| | | | |251215 fois (2.61571+0s) par main::matches à |
|103 | | | |ligne 74 de wordmatch, en moyenne 0.00001s/appel # 9427 |
| | | | |times (0.09628+0s) à la ligne 50 de wordmatch, moy|
| | | | |0.00001s/appel |
| | | | |sub débogage { |
|104 |260642|0.58496 |2e-06 |mon $message = shift; |
|105 | | | | |
|106 |260642|1.09917 |4e-06 |if ( $debug ) { |
|107 | | | |print STDERR "DBG : $message\n" ; |
|108 | | | |} |
|109 | | | |} |
|110 | | | | |
|111 |1 |0.01501 |0.01501|sortie 0; |
|112 | | | | |

Des tas d'informations très utiles là-dedans - cela semble être la voie à suivre.

Voir aussi "Devel::NYTProf::Apache" qui accroche "Devel::NYTProf" dans "mod_perl".

TRI


Les modules Perl ne sont pas les seuls outils dont dispose un analyste des performances,
des outils comme le "temps" ne doivent pas être négligés comme le montre l'exemple suivant, où nous prenons une
coup d'oeil rapide sur le tri. De nombreux livres, thèses et articles ont été écrits sur l'efficacité
algorithmes de tri, et ce n'est pas le lieu de répéter un tel travail, il y a plusieurs bonnes
modules de tri qui méritent aussi d'être examinés : "Sort::Maker", "Sort::Key" ressort à
écouter. Cependant, il est toujours possible de faire quelques observations sur certaines spécificités de Perl
interprétations sur les questions relatives au tri des ensembles de données et donner un ou deux exemples avec
en ce qui concerne la façon dont le tri de gros volumes de données peut affecter les performances. Premièrement, souvent
point négligé lors du tri de grandes quantités de données, on peut tenter de réduire les données
défini pour être traité et dans de nombreux cas, "grep()" peut être très utile comme simple filtre :

@data = trier grep { /$filter/ } @incoming

Une commande comme celle-ci peut réduire considérablement le volume de matériel à trier réellement
en premier lieu, et ne doit pas être négligée à la légère sur la seule base de son
simplicité. Le principe du "KISS" est trop souvent négligé - l'exemple suivant utilise le
utilitaire "temps" système simple à démontrer. Jetons un coup d'oeil à un exemple réel de
trier le contenu d'un gros fichier, un fichier journal apache ferait l'affaire. Celui-ci a plus d'un
un quart de million de lignes, a une taille de 50 M, et un extrait ressemble à ceci :

# fichier journal

188.209-65-87.adsl-dyn.isp.belgacom.be - - [08/Feb/2007:12:57:16 +0000] "GET /favicon.ico HTTP/1.1" 404 209 "-" "Mozilla/ 4.0 (compatible ; MSIE 6.0 ; Windows NT 5.1 ; SV1)"
188.209-65-87.adsl-dyn.isp.belgacom.be - - [08/Feb/2007:12:57:16 +0000] "GET /favicon.ico HTTP/1.1" 404 209 "-" "Mozilla/ 4.0 (compatible ; MSIE 6.0 ; Windows NT 5.1 ; SV1)"
151.56.71.198 - - [08/Feb/2007:12:57:41 +0000] "GET /suse-on-vaio.html HTTP/1.1" 200 2858 "http://www.linux-on-laptops.com/sony.html" "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1"
151.56.71.198 - - [08/Feb/2007:12:57:42 +0000] "GET /data/css HTTP/1.1" 404 206 "http://www.rfi.net/suse-on-vaio.html" "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1"
151.56.71.198 - - [08/Feb/2007:12:57:43 +0000] "GET /favicon.ico HTTP/1.1" 404 209 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.2; en- États-Unis ; rv : 1.8.1.1) Gecko/20061204 Firefox/2.0.0.1"
217.113.68.60 - - [08/Feb/2007:13:02:15 +0000] "GET / HTTP/1.1" 304 - "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
217.113.68.60 - - [08/Feb/2007:13:02:16 +0000] "GET /data/css HTTP/1.1" 404 206 "http://www.rfi.net/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
debora.to.isac.cnr.it - ​​- [08/Feb/2007:13:03:58 +0000] "GET /suse-on-vaio.html HTTP/1.1" 200 2858 "http://www.linux-on-laptops.com/sony.html" "Mozilla/5.0 (compatible; Konqueror/3.4; Linux) KHTML/3.4.0 (comme Gecko)"
debora.to.isac.cnr.it - ​​- [08/Feb/2007:13:03:58 +0000] "GET /data/css HTTP/1.1" 404 206 "http://www.rfi.net/suse-on-vaio.html" "Mozilla/5.0 (compatible; Konqueror/3.4; Linux) KHTML/3.4.0 (comme Gecko)"
debora.to.isac.cnr.it - ​​- [08/Feb/2007:13:03:58 +0000] "GET /favicon.ico HTTP/1.1" 404 209 "-" "Mozilla/5.0 (compatible; Konqueror/ 3.4 ; Linux) KHTML/3.4.0 (comme Gecko)"
195.24.196.99 - - [08/Feb/2007:13:26:48 +0000] "GET / HTTP/1.0" 200 3309 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.9 .20061206) Gecko/1.5.0.9 Firefox/XNUMX"
195.24.196.99 - - [08/Feb/2007:13:26:58 +0000] "GET /data/css HTTP/1.0" 404 206 "http://www.rfi.net/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.9) Gecko/20061206 Firefox/1.5.0.9"
195.24.196.99 - - [08/Feb/2007:13:26:59 +0000] "GET /favicon.ico HTTP/1.0" 404 209 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.9) Gecko/20061206 Firefox/1.5.0.9"
crawl1.cosmixcorp.com - - [08/Feb/2007:13:27:57 +0000] "GET /robots.txt HTTP/1.0" 200 179 "-" "voyager/1.0"
crawl1.cosmixcorp.com - - [08/Feb/2007:13:28:25 +0000] "GET /links.html HTTP/1.0" 200 3413 "-" "voyager/1.0"
fhm226.internetdsl.tpnet.pl - - [08/Feb/2007:13:37:32 +0000] "GET /suse-on-vaio.html HTTP/1.1" 200 2858 "http://www.linux-on-laptops.com/sony.html" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
fhm226.internetdsl.tpnet.pl - - [08/Feb/2007:13:37:34 +0000] "GET /data/css HTTP/1.1" 404 206 "http://www.rfi.net/suse-on-vaio.html" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
80.247.140.134 - - [08/Feb/2007:13:57:35 +0000] "GET / HTTP/1.1" 200 3309 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322 .XNUMX)"
80.247.140.134 - - [08/Feb/2007:13:57:37 +0000] "GET /data/css HTTP/1.1" 404 206 "http://www.rfi.net" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)"
pop.compuscan.co.za - - [08/Feb/2007:14:10:43 +0000] "GET / HTTP/1.1" 200 3309 "-" "www.clamav.net"
livebot-207-46-98-57.search.live.com - - [08/Feb/2007:14:12:04 +0000] "GET /robots.txt HTTP/1.0" 200 179 "-" "msnbot/ 1.0 (+http://search.msn.com/msnbot.htm)"
livebot-207-46-98-57.search.live.com - - [08/Feb/2007:14:12:04 +0000] "GET /html/oracle.html HTTP/1.0" 404 214 "-" " msnbot/1.0 (+http://search.msn.com/msnbot.htm)"
dslb-088-064-005-154.pools.arcor-ip.net - - [08/Feb/2007:14:12:15 +0000] "GET/HTTP/1.1" 200 3309 "-" "www.clamav .rapporter"
196.201.92.41 - - [08/Feb/2007:14:15:01 +0000] "GET / HTTP/1.1" 200 3309 "-" "MOT-L7/08.B7.DCR MIB/2.2.1 Profil/MIDP -2.0 Configuration/CLDC-1.1"

La tâche spécifique ici consiste à trier les 286,525 XNUMX lignes de ce fichier par code de réponse, requête,
Navigateur, URL de référence et enfin Date. Une solution pourrait être d'utiliser le code suivant,
qui itère sur les fichiers donnés sur la ligne de commande.

# journal de tri d'Apache

#!/usr/bin/perl -n

utiliser strict;
utiliser des avertissements ;

mes données;

LIGNE:
tandis que ( <> ) {
ma ligne $ = $_;
si (
$ligne =~ m/^(
([\w\.\-]+) #client
\s*-\s*-\s*\[
([^]]+) #date
\]\s*"\w+\s*
(\S+) # requête
[^"]+"\s*
(\d+) # état
\s+\S+\s+"[^"]*"\s+"
([^"]*) # navigateur
"
.*
)$/x
) {
mes @morceaux = split(/ +/, $line);
mon $ip = $1 ;
ma date $ = 2 $ ;
ma $requête = $3 ;
mon $statut = $4 ;
mon $navigateur = 5 $ ;

push (@data, [$ip, $date, $query, $status, $browser, $line]);
}
}

mon @sorted = trier {
$a->[3] cmp $b->[3]
||
$a->[2] cmp $b->[2]
||
$a->[0] cmp $b->[0]
||
$a->[1] cmp $b->[1]
||
$a->[4] cmp $b->[4]
} @Les données;

foreach mes $données ( @sorted ) {
print $data->[5] ;
}

sortie 0 ;

Lors de l'exécution de ce programme, redirigez "STDOUT" afin qu'il soit possible de vérifier que la sortie est
Corrigez les tests suivants et utilisez l'utilitaire "time" du système pour vérifier l'ensemble
Durée.

$> time ./sort-apache-log logfile > out-sort

réel 0m17.371s
utilisateur 0m15.757s
système 0m0.592s

Le programme a pris un peu plus de 17 secondes d'horloge murale pour s'exécuter. Notez les différentes valeurs "temps"
sorties, il est important de toujours utiliser la même, et de ne pas confondre ce que chacune
signifie.

Temps réel écoulé
Le temps global, ou horloge murale, entre le moment où « heure » ​​a été appelé et le moment où il
se termine. Le temps écoulé comprend les temps utilisateur et système, ainsi que le temps passé
en attente d'autres utilisateurs et processus sur le système. Inévitablement, c'est le plus
approximatif des mesures données.

Temps CPU utilisateur
Le temps de l'utilisateur est le temps que l'ensemble du processus a passé au nom de l'utilisateur sur
ce système exécutant ce programme.

Temps CPU système
Le temps système est le temps que le noyau lui-même a passé à exécuter des routines, ou
appels système, au nom de cet utilisateur de processus.

En exécutant ce même processus comme une "Transformation Schwarzienne", il est possible d'éliminer le
tableaux d'entrée et de sortie pour stocker toutes les données, et travailler sur l'entrée directement comme il
arrive aussi. Sinon, le code est assez similaire :

# sort-apache-log-schwarzian

#!/usr/bin/perl -n

utiliser strict;
utiliser des avertissements ;

impression

carte $_->[0] =>

sorte {
$a->[4] cmp $b->[4]
||
$a->[3] cmp $b->[3]
||
$a->[1] cmp $b->[1]
||
$a->[2] cmp $b->[2]
||
$a->[5] cmp $b->[5]
}
carte [ $_, m/^(
([\w\.\-]+) #client
\s*-\s*-\s*\[
([^]]+) #date
\]\s*"\w+\s*
(\S+) # requête
[^"]+"\s*
(\d+) # état
\s+\S+\s+"[^"]*"\s+"
([^"]*) # navigateur
"
.*
)$/x ]

=> <> ;

sortie 0 ;

Exécutez le nouveau code sur le même fichier journal, comme ci-dessus, pour vérifier la nouvelle heure.

$> time ./sort-apache-log-schwarzian logfile > out-schwarz

réel 0m9.664s
utilisateur 0m8.873s
système 0m0.704s

Le temps a été réduit de moitié, ce qui est une amélioration de vitesse respectable à tous points de vue.
Naturellement, il est important de vérifier que la sortie est cohérente avec la première exécution du programme,
c'est là qu'intervient l'utilitaire "cksum" du système Unix.

$> cksum out-sort out-schwarz
3044173777 52029194 hors tri
3044173777 52029194 hors-schwarz

D'AILLEURS. Attention aussi à la pression des managers qui vous voient accélérer un programme de 50% du
runtime une fois, seulement pour recevoir une demande un mois plus tard pour refaire la même chose (histoire vraie) -
vous n'aurez qu'à souligner que vous n'êtes qu'un humain, même si vous êtes un programmeur Perl, et
tu verras ce que tu peux faire...

Journalisation


Une partie essentielle de tout bon processus de développement est la gestion appropriée des erreurs avec
messages informatifs appropriés, cependant il existe une école de pensée qui
suggère que les fichiers journaux soient bavard, comme si la chaîne de sortie ininterrompue en quelque sorte
assure la pérennité du programme. Si la vitesse est un problème, cette approche est
faux.

Une vue courante est un code qui ressemble à ceci :

logger->debug( "Un message de journalisation via process-id : $$ INC : " . Dumper(\%INC) )

Le problème est que ce code sera toujours analysé et exécuté, même lorsque le débogage
le niveau défini dans le fichier de configuration de journalisation est zéro. Une fois la déboguer() le sous-programme a été
saisie et la variable interne $debug confirmée à zéro, par exemple, le message
qui a été envoyé sera rejeté et le programme continuera. Dans l'exemple
étant donné cependant, le hachage "\%INC" aura déjà été vidé et la chaîne de message
construit, dont tout le travail pourrait être contourné par une variable de débogage à l'instruction
niveau, comme ceci :

logger->debug( "Un message de journalisation via process-id : $$ INC : " . Dumper(\%INC) ) if $DEBUG ;

Cet effet peut être démontré en mettant en place un script de test avec les deux formes, y compris un
Sous-routine "debug()" pour émuler la fonctionnalité "logger()" typique.

#ifdebug

#!/usr/bin/perl

utiliser strict;
utiliser des avertissements ;

utiliser Benchmark ;
utiliser Data::Dumper;
mon $DEBUG = 0 ;

sous-débogage {
mon $msg = décalage ;

si ( $DEBUG ) {
print "DEBUG : $msg\n" ;
}
};

foisces(100000, {
'debug' => sous {
debug( "Un message de journalisation de 0 $ via l'ID de processus : $$" . Dumper(\%INC) )
},
'ifdebug' => sous {
debug( "Un message de journalisation de 0 $ via l'ID de processus : $$" . Dumper(\%INC) ) si $DEBUG
},
});

Voyons ce que "Benchmark" en fait :

$> perl ifdebug
Benchmark : chronométrage 100000 itérations de constante, sous...
ifdebug : 0 s d'horloge murale (0.01 usr + 0.00 sys = 0.01 CPU) @ 10000000.00/s (n=100000)
(attention : trop peu d'itérations pour un comptage fiable)
débogage : 14 secondes d'horloge murale (13.18 usr + 0.04 sys = 13.22 CPU) à 7564.30/s (n=100000)

Dans un cas, le code, qui fait exactement la même chose en ce qui concerne la sortie de n'importe quel
les informations de débogage sont concernées, autrement dit rien, prend 14 secondes, et dans le
dans les autres cas, le code prend un centième de seconde. Semble assez définitif. Utiliser un
Variable $DEBUG AVANT d'appeler la sous-routine, plutôt que de vous fier à la smart
fonctionnalité à l'intérieur.

Journal if DEBUG (constante)
Il est possible de pousser l'idée précédente un peu plus loin, en utilisant un temps de compilation "DEBUG"
constante.

# constante ifdebug

#!/usr/bin/perl

utiliser strict;
utiliser des avertissements ;

utiliser Benchmark ;
utiliser Data::Dumper;
utiliser la constante
DEBOGUER => 0
;

sous-débogage {
si ( DEBOGUER ) {
mon $msg = décalage ;
print "DEBUG : $msg\n" ;
}
};

foisces(100000, {
'debug' => sous {
debug( "Un message de journalisation de 0 $ via l'ID de processus : $$" . Dumper(\%INC) )
},
'constant' => sous {
debug( "Un message de journalisation de 0 $ via l'ID de processus : $$" . Dumper(\%INC) ) si DEBUG
},
});

L'exécution de ce programme produit la sortie suivante :

$> perl ifdebug-constant
Benchmark : chronométrage 100000 itérations de constante, sous...
constante : 0 s d'horloge murale (-0.00 usr + 0.00 sys = -0.00 CPU) @ -7205759403792793600000.00/s (n=100000)
(attention : trop peu d'itérations pour un comptage fiable)
sous : 14 secondes d'horloge murale (13.09 usr + 0.00 sys = 13.09 CPU) @ 7639.42/s (n=100000)

La constante "DEBUG" efface le sol avec même la variable $debug, pointant à moins
zéro seconde, et génère un message « avertissement : trop peu d'itérations pour un nombre fiable »
dans l'affaire. Pour voir ce qui se passe vraiment, et pourquoi nous avons eu trop peu d'itérations quand
nous pensions avoir demandé 100000, nous pouvons utiliser le très utile "B::Deparse" pour inspecter le nouveau
code:

$> perl -MO=Effacer ifdebug-constant

utiliser Benchmark ;
utiliser Data::Dumper;
utiliser la constante ('DEBUG', 0);
sous-débogage {
utiliser des avertissements ;
utiliser des « refs » stricts ;
0;
}
utiliser des avertissements ;
utiliser des « refs » stricts ;
timethes (100000, {'sub', sub {
déboguer "Un message de journalisation à 0 $ via l'ID de processus : $$" . Tombereau(\%INC);
}
, 'constant', sous {
0;
}
});
ifdebug-constant syntaxe OK

La sortie montre le constante() le sous-programme que nous testons est remplacé par la valeur de
la constante "DEBUG" : zéro. La ligne à tester a été complètement optimisée, et
vous ne pouvez pas être beaucoup plus efficace que cela.

POSTSCRIPT


Ce document a fourni plusieurs façons d'identifier les points chauds et de vérifier
si des modifications ont amélioré l'exécution du code.

En guise de dernière réflexion, rappelez-vous qu'il n'est pas (au moment de la rédaction) possible de produire un
programme utile qui fonctionnera en temps zéro ou négatif et ce principe de base peut être
écrit comme : incontournable tout proche. are lent par leur définition même. c'est bien sur possible
d'écrire un programme quasi instantané, mais ça ne va pas faire grand-chose, voici un très
efficace :

$> perl -e 0

Optimiser cela est un travail pour "p5p".

Utilisez perlperf en ligne en utilisant les services onworks.net


Serveurs et postes de travail gratuits

Télécharger des applications Windows et Linux

  • 1
    strass
    strass
    Le projet strace a été déplacé vers
    https://strace.io. strace is a
    diagnostic, débogage et instruction
    traceur d'espace utilisateur pour Linux. C'est utilisé
    surveiller un...
    Télécharger
  • 2
    gMKVExtract GUI
    gMKVExtract GUI
    Une interface graphique pour l'utilitaire mkvextract (qui fait partie de
    MKVToolNix) qui intègre la plupart (si
    pas tous) les fonctionnalités de mkvextract et
    utilitaires mkvinfo. Écrit en C#NET 4.0,...
    Télécharger gMKVExtractGUI
  • 3
    Bibliothèque JasperReports
    Bibliothèque JasperReports
    La bibliothèque JasperReports est la
    l'open source le plus populaire au monde
    veille économique et reporting
    moteur. Il est entièrement écrit en Java
    et il est capable de...
    Télécharger la bibliothèque JasperReports
  • 4
    Livres Frappe
    Livres Frappe
    Frappe Books est une source gratuite et ouverte
    logiciel de comptabilité de bureau
    simple et bien conçu pour être utilisé par
    petites entreprises et indépendants. Ce'...
    Télécharger Frappe Books
  • 5
    Python numérique
    Python numérique
    NEWS : NumPy 1.11.2 est la dernière version
    qui sera fait sur sourceforge. roues
    pour Windows, Mac et Linux ainsi que
    les distributions source archivées peuvent être fou ...
    Télécharger Python numérique
  • 6
    Sphinx de la CMU
    Sphinx de la CMU
    CMUSphinx est un grand locuteur indépendant
    reconnaissance vocale continue de vocabulaire
    publié sous licence de style BSD. Il est
    également une collection d'outils open source ...
    Télécharger CMU Sphinx
  • Plus "

Commandes Linux

crm
crm
Utilisez le CRM en ligne en utilisant onworks.net
prestations de service. ...
Exécuter le CRM
  • 4
    crmgr
    crmgr
    crmgr - utilitaire d'administration pour QDBM
    Curie...
    Exécuter CRMG
  • 5
    visionneuse de trou
    visionneuse de trou
    gappletviewer - Charge et exécute une applet
    Exécuter gappletviewer
  • 6
    lacunes
    lacunes
    mommer - package pour l'alignement de séquences
    de multiples génomes...
    Écarts d'exécution
  • s-processed="true">
    g15stats
    g15stats - Une utilisation CPU/Mémoire/Swap
    compteur pour G15Daemon DESCRIPTION : Le
    packages fournit l'utilisation suivante
    compteur pour LCD sur certains Logitech
    claviers, en utilisant g...
    Exécutez g15stats
  • Plus "
  • Ad