EnglezăFrancezăSpaniolă

Favicon OnWorks

perlperf - Online în cloud

Rulați perlperf în furnizorul de găzduire gratuit OnWorks prin Ubuntu Online, Fedora Online, emulator online Windows sau emulator online MAC OS

Aceasta este comanda perlperf care poate fi rulată în furnizorul de găzduire gratuit OnWorks folosind una dintre multiplele noastre stații de lucru online gratuite, cum ar fi Ubuntu Online, Fedora Online, emulator online Windows sau emulator online MAC OS

PROGRAM:

NUME


perlperf - Tehnici de performanță și optimizare Perl

DESCRIERE


Aceasta este o introducere în utilizarea tehnicilor de performanță și optimizare care pot fi
folosit cu referire specială la programele perl. În timp ce mulți dezvoltatori perl au venit
din alte limbi și își pot folosi cunoștințele anterioare acolo unde este cazul, există multe
alte persoane care ar putea beneficia de câteva indicații specifice perl. Daca vrei ca
versiune condensată, poate cel mai bun sfat vine de la renumitul samurai japonez,
Miyamoto Musashi, care a spus:

„Nu vă angajați în activități inutile”

în 1645.

ÎNSCRIERI


Poate cea mai frecventă greșeală pe care o fac programatorii este să încerce să-și optimizeze codul
înainte ca un program să facă ceva util - aceasta este o idee proastă. Nu are rost
având un program extrem de rapid care nu funcționează. Prima treabă este să obții un program
corect Fă ceva util, (să nu mai vorbim de asigurarea că suita de teste este completă
funcțional), și abia apoi să luăm în considerare optimizarea acestuia. După ce a decis să optimizeze existente
cod de lucru, există câțiva pași simpli, dar esențiali de luat în considerare, care sunt intrinseci
la orice proces de optimizare.

ONE PASUL LATERAL
În primul rând, trebuie să stabiliți un timp de referință pentru codul existent, de care are nevoie
să fie de încredere și repetabil. Probabil că veți dori să utilizați „Evaluarea de referință” sau
Modulele „Devel::NYTProf”, sau ceva similar, pentru acest pas, sau poate sistemul Unix
utilitarul „timp”, oricare este potrivit. Consultați baza acestui document pentru o listă mai lungă
a modulelor de evaluare comparativă și de profilare și a recomandat citiri suplimentare.

ONE PASUL REDIRECŢIONA
Apoi, după ce am examinat programul pentru fierbinte pete, (locuri unde codul pare să ruleze
încet), modificați codul cu intenția de a-l face să ruleze mai repede. Folosind versiunea
software-ul de control, cum ar fi „subversiune”, se va asigura că nicio modificare nu este ireversibilă. Este prea
ușor de lăurat aici și acolo - nu te schimba prea mult la un moment dat, altfel s-ar putea
nu descoperi ce bucată de cod într-adevăr a fost lent.

UN ALT PASUL LATERAL
Nu este suficient să spui: „asta o va face să meargă mai repede”, trebuie să-l verifici. Reluați
cod sub controlul modulelor de benchmarking sau profilare, de la primul pas de mai sus,
și verificați dacă noul cod a executat acelaşi sarcină in mai puțin timp. Salvează-ți munca și
repeta...

GENERAL INSTRUCȚIUNI


Lucrul esențial atunci când luați în considerare performanța este să vă amintiți că nu există așa ceva ca a
„Golden Bullet”, motiv pentru care nu există reguli, doar linii directoare.

Este clar că codul inline va fi mai rapid decât apelurile la subrutine sau la metode,
pentru că sunt mai puține cheltuieli generale, dar această abordare are dezavantajul că este mai mică
întreținută și vine cu prețul unei utilizări mai mari a memoriei - nu există așa ceva ca a
pranz gratuit. Dacă căutați un element dintr-o listă, poate fi mai eficient
stocați datele într-o structură hash și apoi uitați-vă pur și simplu pentru a vedea dacă este cheia
definit, mai degrabă decât să parcurgem întreaga matrice folosind grep() de exemplu. substr()
poate fi (mult) mai rapid decât grep() dar nu la fel de flexibil, așa că aveți un alt compromis
acces. Codul dvs. poate conține o linie care durează 0.01 secundă pentru a se executa, ceea ce dacă dvs
numiți-o de 1,000 de ori, foarte probabil într-un program care analizează chiar și fișiere de dimensiune medie
De exemplu, aveți deja o întârziere de 10 secunde, într-o singură locație de cod și dacă aveți
apelați acea linie de 100,000 de ori, întregul dvs. program va încetini până la un crawl insuportabil.

Folosirea unei subrutine ca parte a sortării dvs. este o modalitate puternică de a obține exact ceea ce doriți,
dar va fi de obicei mai lent decât cel încorporat alfabetic „cmp” și numeric sortare „<=>”.
operatori. Este posibil să faceți mai multe treceri peste datele dvs., construind indici pentru
face sortarea viitoare mai eficientă și să folosești ceea ce este cunoscut sub numele de „OM” (Orcish
Manevră) pentru a stoca în cache cheile de sortare în avans. Căutarea în cache, deși este o idee bună, poate
în sine să fie o sursă de încetinire prin aplicarea unei duble treceri peste date - o dată la configurare
memoria cache și o dată pentru a sorta datele. Folosind „pack()” pentru a extrage cheia de sortare necesară
într-un șir consistent poate fi o modalitate eficientă de a construi un singur șir de comparat,
în loc să folosiți mai multe chei de sortare, ceea ce face posibilă utilizarea standardului scris
în „c” și rapid, funcția perl „sort()” la ieșire și este baza „GRT”
(Transformarea Guttman Rossler). Unele combinații de șiruri pot încetini „GRT”, doar
fiind prea simplu complex pentru binele său.

Pentru aplicațiile care folosesc baze de date, spațiul de nume standard „DBIX” încearcă să ajute
cu menținerea lucrurilor atrăgătoare, nu în ultimul rând pentru că încearcă nu interogați baza de date până la
cel mai recent moment posibil, dar citiți întotdeauna documentele care vin cu bibliotecile alese.
Printre multele probleme cu care se confruntă dezvoltatorii care se ocupă cu bazele de date ar trebui să rămână conștienți de este
să folosiți întotdeauna substituenți „SQL” și să luați în considerare preluarea seturilor de date atunci când acest lucru s-ar putea
se dovedesc avantajos. Împărțirea unui fișier mare prin alocarea mai multor procese pentru analiza
un singur fișier, folosind „POE”, „threads” sau „furk” poate fi, de asemenea, o modalitate utilă de optimizare
utilizarea de către dvs. a resurselor „CPU” disponibile, deși această tehnică este plină
probleme de concurență și necesită o mare atenție la detalii.

Fiecare caz are o aplicație specifică și una sau mai multe excepții și nu există
înlocuitor pentru a efectua câteva teste și pentru a afla care metodă funcționează cel mai bine pentru dvs
mediu particular, acesta este motivul pentru care scrierea codului optim nu este o știință exactă și de ce
ne place atât de mult să folosim Perl - TMTOWTDI.

REPERE


Iată câteva exemple pentru a demonstra utilizarea instrumentelor de benchmarking ale Perl.

Atribuire si Dereferențiere Variabile
Sunt sigur că majoritatea dintre noi au văzut cod care arată ca, (sau mai rău decât), acesta:

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

Acest tip de cod poate fi o adevărată criză de citit, precum și foarte sensibil la greșeli de scriere,
și este mult mai clar să dereferiți variabila în mod explicit. Ocolim
problema de lucru cu tehnici de programare orientată pe obiecte pentru a încapsula variabile
acces prin metode, accesibil doar printr-un obiect. Aici doar discutăm despre
implementarea tehnică la alegere și dacă aceasta are un efect asupra performanței. Putem
vezi dacă această operație de dereferențiere are vreo suprasarcină prin introducerea unui cod comparativ
un fișier și rulează un test „Benchmark”.

# dereferință

#!/usr/bin/perl

folosiți strict;
folosiți avertismente;

utilizați Benchmark;

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

timethese(1000000, {
„direct” => sub {
my $x = $ref->{ref}->{_myscore} . $ref->{ref}->{_yourscore} ;
},
'dereference' => sub {
my $ref = $ref->{ref};
my $myscore = $ref->{_myscore};
my $yourscore = $ref->{_yourscore};
my $x = $myscore . $punctul tau;
},
});

Este esențial să efectuați orice măsurători de cronometrare de un număr suficient de ori, astfel încât numerele
stabiliți-vă pe o medie numerică, altfel fiecare rulare va fluctua în mod natural din cauza
variaţiile mediului, pentru a reduce efectul de dispută pentru resursele „CPU” şi
lățimea de bandă a rețelei, de exemplu. Rulând codul de mai sus pentru un milion de iterații, putem
aruncați o privire la rezultatul raportului de către modulul „Benchmark”, pentru a vedea care este abordarea
cel mai eficient.

$> dereferire perl

Benchmark: sincronizare 1000000 de iterații de dereferire, direct...
dereferință: 2 secunde wallclock (1.59 usr + 0.00 sys = 1.59 CPU) @ 628930.82/s (n=1000000)
direct: 1 wallclock secunde (1.20 usr + 0.00 sys = 1.20 CPU) @ 833333.33/s (n=1000000)

Diferența este clar de văzut, iar abordarea dereferențării este mai lentă. În timp ce s-a descurcat
pentru a executa o medie de 628,930 de ori pe secundă în timpul testului nostru, abordarea directă
a reușit să ruleze încă 204,403 de ori, din păcate. Din păcate, pentru că acolo
sunt multe exemple de cod scris folosind accesul direct variabil multiplu și
de obicei este oribil. Este, totuși, minuscul mai rapid. Rămâne întrebarea dacă
câștigul minut merită de fapt oboseala ochilor sau pierderea capacității de întreținere.

Caută si înlocui or tr
Dacă avem un șir care trebuie modificat, în timp ce un regex va fi aproape întotdeauna mult
mai flexibil, „tr”, un instrument adesea subutilizat, poate fi totuși un util. Un scenariu ar putea fi
înlocuiți toate vocalele cu un alt caracter. Soluția regex ar putea arăta astfel:

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

Alternativa „tr” ar putea arăta astfel:

$str =~ tr/aeiou//

Putem pune asta într-un fișier de testare pe care îl putem rula pentru a verifica care abordare este cea mai rapidă,
folosind o variabilă globală $STR pentru a se atribui variabilei „my $str” pentru a evita perl
încercând să optimizați oricare dintre lucrări, observând că este atribuită doar o singură dată.

# regex-transliterat

#!/usr/bin/perl

folosiți strict;
folosiți avertismente;

utilizați Benchmark;

my $STR = "$$-aceasta și aia";

timethese( 1000000, {
'sr' => sub { my $str = $STR; $str =~ s/[aeiou]/x/g; returnează $str; },
'tr' => sub { my $str = $STR; $str =~ tr/aeiou//; returnează $str; },
});

Rularea codului ne oferă rezultatele noastre:

$> perl regex-transliterate

Benchmark: cronometrarea 1000000 de iterații de sr, tr...
sr: 2 secunde wallclock (1.19 usr + 0.00 sys = 1.19 CPU) @ 840336.13/s (n=1000000)
tr: 0 secunde wallclock (0.49 usr + 0.00 sys = 0.49 CPU) @ 2040816.33/s (n=1000000)

Versiunea „tr” este un câștigător clar. O soluție este flexibilă, cealaltă este rapidă - și
este alegerea adecvată a programatorului pe care să o folosească.

Consultați documentele „Evaluare de referință” pentru alte tehnici utile.

PROFILARE UNELTE


O bucată de cod puțin mai mare va oferi ceva pe care un profiler poate produce
statistici de raportare mai extinse. Acest exemplu folosește programul simplist „wordmatch”.
care analizează un anumit fișier de intrare și scoate un scurt raport asupra conținutului.

# potrivire de cuvinte

#!/usr/bin/perl

folosiți strict;
folosiți avertismente;

=head1 NUME

filewords - analiza cuvintelor fișierului de intrare

=head1 SINOPSIS

cuvinte-fișier -f intrarenume fișier [-d]

=head1 DESCRIERE

Acest program analizează numele fișierului dat, specificat cu C<-f>, și afișează a
simplă analiză a cuvintelor găsite în el. Utilizați comutatorul C<-d> pentru a activa
mesaje de depanare.

=tăiat

utilizați FileHandle;
utilizați Geopt::Long;

my $debug = 0;
my $file = '';

my $result = GetOptions (
'debug' => \$debug,
'file=s' => \$fișier,
);
die("arg-uri invalide") cu excepția cazului în care $result;

cu excepția cazului în care ( -f $fișier ) {
die("Utilizare: $0 -f nume de fișier [-d]");
}
my $FH = FileHandle->new ("< $fișier") sau die ("nu se poate deschide fișierul ($fișier): $!");

my $i_LINES = 0;
my $i_WORDS = 0;
meu %count = ();

@liniile mele = <$FH>;
foreach my $line ( @lines ) {
$i_LINES++;
$linie =~ s/\n//;
my @words = split(/ +/, $line);
my $i_words = scalar(@words);
$i_CUVINTE = $i_CUVINTE + $i_cuvinte;
debug("linie: $i_LINES care furnizează $i_words cuvinte: @words");
my $i_word = 0;
foreach my $word ( @words ) {
$i_word++;
$număr{$i_LINES}{spec} += se potrivește($i_word, $word, '[^a-zA-Z0-9]');
$număr{$i_LINES}{doar} += se potrivește($i_word, $word, '^[^a-zA-Z0-9]+$');
$număr{$i_LINES}{cons} += se potrivește($i_word, $word, '^[(?i:bcdfghjklmnpqrstvwxyz)]+$');
$count{$i_LINES}{jurăminte} += se potrivește($i_word, $word, '^[(?i:aeiou)]+$');
$count{$i_LINES}{caps} += potriviri($i_word, $word, '^[(AZ)]+$');
}
}

imprimare raport (%count);

sub potriviri {
my $i_wd = shift;
my $word = shift;
my $regex = shift;
my $has = 0;

dacă ( $cuvânt =~ /($regex)/ ) {
$has++ dacă $1;
}

debug("cuvânt: $i_wd ".($are ? 'potrivește': 'nu se potrivește')." caractere: /$regex/");

return $has;
}

sub raport {
%raportul meu = @_;
meu %rep;

foreach my $line ( chei %report ) {
foreach my $key ( chei %{ $report{$line} } ) {
$rep{$key} += $report{$line}{$key};
}
}

$raportul meu = qq|
Raport $0 pentru $file:
linii în fișier: $i_LINES
cuvinte din fișier: $i_WORDS
cuvinte cu caractere speciale (non-cuvânt): $i_spec
cuvinte cu doar caractere speciale (non-cuvânt): $i_only
cuvinte cu numai consoane: $i_cons
cuvinte cu doar majuscule: $i_caps
cuvinte cu numai vocale: $i_vows
|;

returnează $raport;
}

sub depanare {
my $message = shift;

if ( $debug ) {
print STDERR "DBG: $mesaj\n";
}
}

ieșirea 0;

Dezvoltare::DProf
Acest modul venerabil a fost standardul de facto pentru profilarea codului Perl de mai mult
un deceniu, dar a fost înlocuit cu o serie de alte module la care ne-au adus înapoi
secolul 21. Deși vi se recomandă să vă evaluați instrumentul din mai multe
menționat aici și din lista CPAN de la baza acestui document, (și în prezent
Devel::NYTProf pare să fie arma preferată - vezi mai jos), vom arunca o privire rapidă la
ieșirea de la Devel::DProf mai întâi, pentru a seta o linie de bază pentru instrumentele de profilare Perl. Rulați
programul de mai sus sub controlul „Devel::DProf” folosind comutatorul „-d” de pe comanda-
linia.

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

<...mai multe linii tăiate...>

raport de potrivire a cuvintelor pentru perl5db.pl:
rânduri în dosar: 9428
cuvinte din dosar: 50243
cuvinte cu caractere speciale (non-cuvânt): 20480
cuvinte cu doar caractere speciale (non-cuvinte): 7790
cuvinte cu numai consoane: 4801
cuvinte cu doar majuscule: 1316
cuvinte cu numai vocale: 1701

„Devel::DProf” produce un fișier special, numit tmon.out implicit și acest fișier este citit
de programul „dprofpp”, care este deja instalat ca parte a „Devel::DProf”
distributie. Dacă apelați „dprofpp” fără opțiuni, va citi tmon.out fișier în
directorul curent și să producă un raport de statistici care poate fi citit de om al rulării dvs
program. Rețineți că acest lucru poate dura puțin timp.

$> dprofpp

Timp total scurs = 2.951677 secunde
Timp utilizator+sistem = 2.871677 secunde
Timpuri exclusive
%Time ExclSec CumulS #Calls sec/call Csec/c Name
102. 2.945 3.003 251215 0.0000 0.0000 principal::meciuri
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::raport
1.04 0.030 0.049 4 0.0075 0.0123 main::BEGIN
0.35 0.010 0.010 3 0.0033 0.0033 Exportator::as_heavy
0.35 0.010 0.010 7 0.0014 0.0014 IO::Fișier::BEGIN
0.00 - -0.000 1 - - Getopt::Long::FindOption
0.00 - -0.000 1 - - Simbol::BEGIN
0.00 - -0.000 1 - - Fcntl::BEGIN
0.00 - -0.000 1 - - Fcntl::bootstrap
0.00 - -0.000 1 - - avertismente::BEGIN
0.00 - -0.000 1 - - IO::bootstrap
0.00 - -0.000 1 - - Geopt::Long::ConfigDefaults
0.00 - -0.000 1 - - Geopt::Long::Configurare
0.00 - -0.000 1 - - Simbol::gensym

„dprofpp” va produce niște rapoarte destul de detaliate despre activitatea „wordmatch”
program. Ceasul de perete, utilizatorul și sistemul, timpii sunt în partea de sus a analizei și după
acestea sunt principalele coloane care definesc raportul. Verificați documentele „dprofpp” pentru
detalii despre numeroasele opțiuni pe care le acceptă.

Vezi și „Apache::DProf” care conectează „Devel::DProf” în „mod_perl”.

Devel::Profiler
Să aruncăm o privire la același program folosind un alt profiler: „Devel::Profiler”, a
Înlocuire integrată numai în Perl pentru „Devel::DProf”. Utilizarea este foarte ușor diferită în
că, în loc să utilizați indicatorul special „-d:”, trageți „Devel::Profiler” direct ca un
modul folosind „-M”.

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

<...mai multe linii tăiate...>

raport de potrivire a cuvintelor pentru perl5db.pl:
rânduri în dosar: 9428
cuvinte din dosar: 50243
cuvinte cu caractere speciale (non-cuvânt): 20480
cuvinte cu doar caractere speciale (non-cuvinte): 7790
cuvinte cu numai consoane: 4801
cuvinte cu doar majuscule: 1316
cuvinte cu numai vocale: 1701

„Devel::Profiler” generează un fișier tmon.out care este compatibil cu „dprofpp”
program, salvând astfel construcția unui program dedicat cititor de statistici. "dprofpp"
utilizarea este, prin urmare, identică cu exemplul de mai sus.

$> dprofpp

Timp total scurs = 20.984 secunde
Timp utilizator+sistem = 19.981 secunde
Timpuri exclusive
%Time ExclSec CumulS #Calls sec/call Csec/c Name
49.0 9.792 14.509 251215 0.0000 0.0001 principal::meciuri
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::raport
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::Fișier::nou
0.00 0.000 0.000 1 0.0000 0.0000 IO::Mâner::nou
0.00 0.000 0.000 1 0.0000 0.0000 Simbol::gensym
0.00 0.000 0.000 1 0.0000 0.0000 IO::Fișier::deschis

Interesant, obținem rezultate ușor diferite, ceea ce se datorează în mare parte algoritmului
care generează raportul este diferit, chiar dacă se presupune că formatul fișierului de ieșire a fost
identic. Timpul scurs, de utilizator și de sistem arată clar timpul necesar
„Devel::Profiler” pentru a-și executa propria rulare, dar listele coloanelor par mai precise
cumva decât cele pe care le aveam mai devreme de la „Devel::DProf”. Cifra de 102% are
a dispărut, de exemplu. Aici trebuie să folosim instrumentele pe care le avem la dispoziție și
recunoașteți-le avantajele și dezavantajele, înainte de a le folosi. Interesant, numărul de apeluri pentru
fiecare subrutină este identică în cele două rapoarte, procentele diferă. La fel de
autorul cărții „Devel::Proviler” scrie:

... rulează suita de testare HTML::Template sub Devel::DProf arată output()
NU ia timp, dar Devel::Profiler arată că aproximativ 10% din timp este în output().
Nu știu în care să am încredere, dar instinctul îmi spune că ceva nu este în regulă
Dezvoltare::DProf. HTML::Template::output() este o rutină mare pentru care se cere
fiecare test. Oricum, ceva trebuie reparat.

YMMV.

Vezi și „Devel::Apache::Profiler” care conectează „Devel::Profiler” în „mod_perl”.

Dezvoltare::SmallProf
Profilerul „Devel::SmallProf” examinează timpul de execuție al programului dvs. Perl și produce a
listare rând cu linie pentru a arăta de câte ori a fost apelată fiecare linie și cât de lungă fiecare linie
a luat să execute. Este apelat prin furnizarea cunoscutului steag „-d” lui Perl în timpul execuției.

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

<...mai multe linii tăiate...>

raport de potrivire a cuvintelor pentru perl5db.pl:
rânduri în dosar: 9428
cuvinte din dosar: 50243
cuvinte cu caractere speciale (non-cuvânt): 20480
cuvinte cu doar caractere speciale (non-cuvinte): 7790
cuvinte cu numai consoane: 4801
cuvinte cu doar majuscule: 1316
cuvinte cu numai vocale: 1701

„Devel::SmallProf” scrie rezultatul într-un fișier numit micprof.out, în mod implicit. The
formatul fișierului arată astfel:

:

Când programul sa încheiat, rezultatul poate fi examinat și sortat folosind orice standard
utilitare de filtrare a textului. Ceva de genul următor poate fi suficient:

$> cat smallprof.out | grep \d*: | sortare -k3 | tac | cap -n20

251215 1.65674 7.68000 75: dacă ( $cuvânt =~ /($regex)/ ) {
251215 0.03264 4.40000 79: depanare("cuvânt: $i_wd ".($are ? 'potriviri':
251215 0.02693 4.10000 81: return $has;
260643 0.02841 4.07000 128: if ( $debug ) {
260643 0.02601 4.04000 126: mesajul meu $ = shift;
251215 0.02641 3.91000 73: my $has = 0;
251215 0.03311 3.71000 70: my $i_wd = shift;
251215 0.02699 3.69000 72: my $regex = shift;
251215 0.02766 3.68000 71: cuvantul meu $ = shift;
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: my $i_cons = potrivește($i_word, $word,
50243 0.48837 0.88000 63: $count{$i_LINES}{caps} =
50243 0.00516 0.88000 58: my $i_caps = potrivește($i_word, $word, '^[(A-
50243 0.00631 0.81000 54: my $i_spec = se potrivește($i_word, $word, '[^a-
50243 0.00496 0.80000 57: jurămintele mele $i = se potrivește($i_word, $word,
50243 0.00688 0.80000 53: $i_word++;
50243 0.48469 0.79000 62: $count{$i_LINES}{numai} =
50243 0.48928 0.77000 60: $count{$i_LINES}{vows} =

50243 0.00683 0.75000 55: my $i_only = potrivește($i_word, $word, '^[^a-
Puteți vedea imediat o focalizare ușor diferită față de modulele de profilare a subrutinei,
și începem să vedem exact care linie de cod durează cel mai mult timp. Acea linie regex
pare un pic suspect, de exemplu. Amintiți-vă că aceste instrumente ar trebui să fie
folosite împreună, nu există o singură modalitate cea mai bună de a vă profila codul, trebuie să utilizați cel mai bun
instrumente pentru muncă.

Vezi și „Apache::SmallProf” care conectează „Devel::SmallProf” în „mod_perl”.

Dezvoltare::FastProf
„Devel::FastProf” este un alt profil de linie Perl. Acesta a fost scris cu scopul de a obține
un profiler de linii mai rapid decât este posibil cu, de exemplu, „Devel::SmallProf”, pentru că este
scris cu „C”. Pentru a utiliza „Devel::FastProf”, furnizați argumentul „-d” lui Perl:

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

<...mai multe linii tăiate...>

raport de potrivire a cuvintelor pentru perl5db.pl:
rânduri în dosar: 9428
cuvinte din dosar: 50243
cuvinte cu caractere speciale (non-cuvânt): 20480
cuvinte cu doar caractere speciale (non-cuvinte): 7790
cuvinte cu numai consoane: 4801
cuvinte cu doar majuscule: 1316
cuvinte cu numai vocale: 1701

„Devel::FastProf” scrie statistici în fișier fastprof.out în directorul curent.
Fișierul de ieșire, care poate fi specificat, poate fi interpretat folosind „fprofpp”
program de linie de comandă.

$> fprofpp | cap -n20

Formatul de ieșire # fprofpp este:
# filename:line time count: source
potrivire cuvinte:75 3.93338 251215: dacă ( $cuvânt =~ /($regex)/ ) {
wordmatch:79 1.77774 251215: debug("cuvânt: $i_wd ".($are ? 'potriviri': 'nu se potrivește')." caractere: /$regex/");
potrivire cuvinte:81 1.47604 251215: return $has;
potrivire cuvinte:126 1.43441 260643: mesajul meu $ = shift;
potrivire cuvinte:128 1.42156 260643: if ( $debug ) {
wordmatch:70 1.36824 251215: my $i_wd = shift;
potrivire cuvinte:71 1.36739 251215: my $word = shift;
potrivire cuvinte:72 1.35939 251215: my $regex = shift;

Imediat putem vedea că numărul de ori a fost apelată fiecare linie este identic cu
ieșirea „Devel::SmallProf”, iar secvența este doar foarte puțin diferită în funcție de
ordonarea timpului necesar fiecărei linii pentru a se executa, „dacă ( $debug ) { ” și „my
$message = shift;", de exemplu. Diferențele de timp real înregistrate ar putea fi în
algoritmul utilizat intern sau poate fi din cauza limitărilor resurselor sistemului sau
disputa.

Vedeți și DBIx::Profile care va profila interogările bazei de date care rulează sub „DBIX::*”
spațiu de nume.

Dezvoltare::NYTProf
„Devel::NYTProf” este următor generaţie de profiler de coduri Perl, remediind multe deficiențe în
alte instrumente și implementarea multor caracteristici interesante. În primul rând, poate fi folosit fie ca a
linie profiler, a bloca sau un subrutină profiler, toate deodată. De asemenea, poate folosi sub-
rezoluție în microsecunde (100ns) pe sistemele care oferă „clock_gettime()”. Poate fi
pornit și oprit chiar și de programul care este profilat. Este o intrare cu o singură linie în profil
aplicații „mod_perl”. Este scris cu „c” și este probabil cel mai rapid profiler
disponibil pentru Perl. Lista de răcoare continuă. Destul de asta, hai să vedem cum
funcționează - folosește comutatorul familiar „-d” pentru a-l conecta și a rula codul.

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

raport de potrivire a cuvintelor pentru perl5db.pl:
rânduri în dosar: 9427
cuvinte din dosar: 50243
cuvinte cu caractere speciale (non-cuvânt): 20480
cuvinte cu doar caractere speciale (non-cuvinte): 7790
cuvinte cu numai consoane: 4801
cuvinte cu doar majuscule: 1316
cuvinte cu numai vocale: 1701

„NYTProf” va genera o bază de date de raport în fișier nytprof.out în mod implicit. Uman
rapoarte care pot fi citite pot fi generate de aici utilizând „nytprofhtml” (HTML
ieșire) și programele „nytprofcsv” (ieșire CSV). Am folosit sistemul Unix „html2text”
utilitate pentru a converti nytprof/index.html dosar pentru comoditate aici.

$> html2text nytprof/index.html

Indicele profilului de performanță
Pentru potrivirea cuvintelor
Rulați vineri, 26 septembrie 13:46:39 2008
Raportat vineri, 26 septembrie 13:47:23 2008

Top 15 subrutine -- ordonate după ora exclusivă
|Apeluri |P |F |Inclusiv|Exclusiv|Subrutină |
| | | |Timp |Timp | |
|251215|5 |1 |13.09263 |10.47692 |principal:: |meciuri |
|260642|2 |1 |2.71199 |2.71199 |main:: |debug |
|1 |1 |1 |0.21404 |0.21404 |principal:: |raport |
|2 |2 |2 |0.00511 |0.00511 |XSLoader:: |încărcare (xsub) |
|14 |14|7 |0.00304 |0.00298 |Exportator:: |import |
|3 |1 |1 |0.00265 |0.00254 |Exportator:: |ca_grele |
|10 |10|4 |0.00140 |0.00140 |vars:: |import |
|13 |13|1 |0.00129 |0.00109 |constant:: |import |
|1 |1 |1 |0.00360 |0.00096 |FileHandle:: |import |
|3 |3 |3 |0.00086 |0.00074 |avertismente::registru::|import |
|9 |3 |1 |0.00036 |0.00036 |strict:: |biți |
|13 |13|13|0.00032 |0.00029 |strict:: |import |
|2 |2 |2 |0.00020 |0.00020 |avertismente:: |import |
|2 |1 |1 |0.00020 |0.00020 |Getopt::Long:: |ParseOptionSpec|
|7 |7 |6 |0.00043 |0.00020 |strict:: |unimport |

Pentru mai multe informații, consultați lista completă a 189 de subrutine.

Prima parte a raportului arată deja informațiile critice cu privire la care
subrutinele folosesc cel mai mult timp. Următorul oferă câteva statistici despre sursă
fișiere profilate.

Fișierele cod sursă -- ordonate după oră exclusivă, apoi nume
|Stmts |Exclusiv|Media |Rapoarte |Fișier sursă |
| |Timp | | | |
|2699761|15.66654 |6e-06 |linia . bloc . sub|potrivire de cuvinte |
|35 |0.02187 |0.00062|linie . bloc . sub|IO/Handle.pm |
|274 |0.01525 |0.00006|linie . bloc . sub|Getopt/Long.pm |
|20 |0.00585 |0.00029|linie . bloc . sub|Fcntl.pm |
|128 |0.00340 |0.00003|linie . bloc . sub|Exportator/Heavy.pm |
|42 |0.00332 |0.00008|linie . bloc . sub|IO/File.pm |
|261 |0.00308 |0.00001|linie . bloc . sub|Exportator.pm |
|323 |0.00248 |8e-06 |linia . bloc . sub|constant.pm |
|12 |0.00246 |0.00021|linie . bloc . sub|Fișier/Spec/Unix.pm |
|191 |0.00240 |0.00001|linie . bloc . sub|vars.pm |
|77 |0.00201 |0.00003|linie . bloc . sub|FileHandle.pm |
|12 |0.00198 |0.00016|linie . bloc . sub|Carp.pm |
|14 |0.00175 |0.00013|linie . bloc . sub|Simbol.pm |
|15 |0.00130 |0.00009|linie . bloc . sub|IO.pm |
|22 |0.00120 |0.00005|linie . bloc . sub|IO/Seekable.pm |
|198 |0.00085 |4e-06 |linie . bloc . sub|avertismente/registru.pm|
|114 |0.00080 |7e-06 |linia . bloc . sub|strict.pm |
|47 |0.00068 |0.00001|linie . bloc . sub|avertismente.pm |
|27 |0.00054 |0.00002|linie . bloc . sub|supraîncărcare.pm |
|9 |0.00047 |0.00005|linie . bloc . sub|SelectSaver.pm |
|13 |0.00045 |0.00003|linie . bloc . sub|Fișier/Spec.pm |
|2701595|15.73869 | |Total |
|128647 |0.74946 | |Medie |
| |0.00201 |0.00003|Median |
| |0.00121 |0.00003|Abatere |

Raport produs de NYTProf 2.03 Perl profiler, dezvoltat de Tim Bunce și
Adam Kaplan.

În acest moment, dacă utilizați html raport, puteți face clic pe diferitele link-uri către
găurit în fiecare subrutină și fiecare linie de cod. Pentru că folosim textul
raportare aici și există un întreg director plin de rapoarte construite pentru fiecare fișier sursă,
Vom afișa doar o parte din corespunzătoare wordmatch-line.html dosar, suficient pentru
dați o idee despre tipul de rezultate la care vă puteți aștepta de la acest instrument grozav.

$> html2text nytprof/wordmatch-line.html

Profil de performanță -- -vizualizare bloc-.-vizualizare linie-.-vizualizare secundară-
Pentru potrivirea cuvintelor
Rulați vineri, 26 septembrie 13:46:39 2008
Raportat vineri, 26 septembrie 13:47:22 2008

Fișierul wordmatch

Subrutine -- ordonate după ora exclusivă
|Apeluri |P|F|Inclusiv|Exclusiv|Subrutină |
| | | |Timp |Timp | |
|251215|5|1|13.09263 |10.47692 |main::|matches|
|260642|2|1|2.71199 |2.71199 |main::|debug |
|1 |1|1|0.21404 |0.21404 |principal::|raport |
|0 |0|0|0 |0 |main::|BEGIN |

|Linie|Stmts.|Exclusiv|Media |Cod |
| | |Timp | | |
|1 | | | |#!/usr/bin/perl |
|2 | | | | |
| | | | |utilizare strictă; |
|3 |3 |0.00086 |0.00029|# a petrecut 0.00003s efectuând 1 apeluri către strict:: |
| | | | |import |
| | | | |avertismente de utilizare; |
|4 |3 |0.01563 |0.00521|# a petrecut 0.00012s efectuând 1 apeluri la avertismente:: |
| | | | |import |
|5 | | | | |
|6 | | | |=head1 NUME |
|7 | | | | |
|8 | | | |filewords - analiza cuvintelor fisierului de intrare |
<...snip...>
|62 |1 |0.00445 |0.00445|print report( %count ); |
| | | | |# a petrecut 0.21404 secunde efectuând 1 apeluri către main::report|
|63 | | | | |
| | | | |# a petrecut 23.56955s (10.47692+2.61571) în |
| | | | |main::meciuri care au fost apelate de 251215 ori, |
| | | | |în medie 0.00005s/apel: # 50243 ori |
| | | | |(2.12134+0.51939s) la rândul 57 al potrivirii cuvintelor, avg|
| | | | |0.00005s/call # 50243 ori (2.17735+0.54550s) |
|64 | | | |la rândul 56 al potrivirii cuvintelor, în medie 0.00005 s/apel # |
| | | | |50243 ori (2.10992+0.51797s) la rândul 58 din |
| | | | |potrivire de cuvinte, în medie 0.00005 s/apel # 50243 ori |
| | | | |(2.12696+0.51598s) la rândul 55 al potrivirii cuvintelor, avg|
| | | | |0.00005s/call # 50243 ori (1.94134+0.51687s) |
| | | | |la rândul 54 al potrivirii cuvintelor, în medie 0.00005 s/apel |
| | | | |sub potriviri { |
<...snip...>
|102 | | | | |
| | | | |# a petrecut 2.71199 s în main::debug care a fost |
| | | | |apelat de 260642 ori, în medie 0.00001s/apel: # |
| | | | |251215 ori (2.61571+0s) după principal::meciuri la |
|103 | | | |linia 74 a potrivirii cuvintelor, în medie 0.00001 s/apel # 9427 |
| | | | |ori (0.09628+0s) la rândul 50 al potrivirii cuvintelor, avg|
| | | | |0.00001s/apel |
| | | | |sub depanare { |
|104 |260642|0.58496 |2e-06 |mesajul meu $ = shift; |
|105 | | | | |
|106 |260642|1.09917 |4e-06 |dacă ( $debug ) { |
|107 | | | |printează STDERR „DBG: $mesaj\n”; |
|108 | | | |} |
|109 | | | |} |
|110 | | | | |
|111 |1 |0.01501 |0.01501|ieșire 0; |
|112 | | | | |

O mulțime de informații foarte utile acolo - aceasta pare să fie calea de urmat.

Vezi și „Devel::NYTProf::Apache” care conectează „Devel::NYTProf” în „mod_perl”.

TRIERE


Modulele Perl nu sunt singurele instrumente pe care un analist de performanță le are la dispoziție, sistemul
instrumente precum „timpul” nu trebuie trecute cu vederea, așa cum arată următorul exemplu, unde luăm a
privire rapidă la sortare. S-au scris multe cărți, teze și articole despre eficiență
algoritmi de sortare, iar acesta nu este locul pentru a repeta o astfel de muncă, există mai multe bune
module de sortare care merită să aruncăm o privire și la: „Sort::Maker”, „Sort::Key” primesc la
minte. Cu toate acestea, este încă posibil să faceți câteva observații cu privire la anumite caracteristici Perl
interpretări asupra problemelor legate de sortarea seturilor de date și dați un exemplu sau două cu
în ceea ce privește modul în care sortarea unor volume mari de date poate afecta performanța. În primul rând, de multe ori
punct trecut cu vederea atunci când sortați cantități mari de date, se poate încerca să reducă datele
setat pentru a fi tratat și în multe cazuri „grep()” poate fi destul de util ca un filtru simplu:

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

O astfel de comandă poate reduce considerabil volumul de material de sortat efectiv
în primul rând, și nu ar trebui să fie neglijat prea ușor doar pe baza acesteia
simplitate. Principiul „Sărut” este prea des trecut cu vederea - exemplul următor folosește
sistem simplu "timp" utilitar pentru a demonstra. Să aruncăm o privire la un exemplu real de
sortarea conținutului unui fișier mare, un fișier jurnal Apache ar face. Acesta are peste a
un sfert de milion de linii, are o dimensiune de 50 de milioane și un fragment din el arată astfel:

# fișier jurnal

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 (compatibil; 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 (compatibil; 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; ro- SUA; 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 (compatibil; 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 (compatibil; 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 (compatibil; Konqueror/3.4; Linux) KHTML/3.4.0 (cum ar fi 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 (compatibil; Konqueror/3.4; Linux) KHTML/3.4.0 (cum ar fi Gecko)"
debora.to.isac.cnr.it - ​​- [08/Feb/2007:13:03:58 +0000] „GET /favicon.ico HTTP/1.1” 404 209 „-” „Mozilla/5.0 (compatibil; Konqueror/ 3.4; Linux) KHTML/3.4.0 (cum ar fi 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 (compatibil; 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 (compatibil; 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 (compatibil; MSIE 6.0; Windows NT 5.1; .NET CLR); .1.1.4322)"
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 (compatibil; 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 .net"
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 Configurație/CLDC-1.1"

Sarcina specifică aici este de a sorta cele 286,525 de linii ale acestui fișier după cod de răspuns, interogare,
Browser, URL de referință și, în sfârșit, Data. O soluție ar putea fi folosirea următorului cod,
care iterează peste fișierele date pe linia de comandă.

# sort-apache-log

#!/usr/bin/perl -n

folosiți strict;
folosiți avertismente;

datele mele;

LINIA:
în timp ce ( <> ) {
my $line = $_;
dacă (
$linie =~ m/^(
([\w\.\-]+) # client
\s*-\s*-\s*\[
([^]]+) # dată
\]\s*"\w+\s*
(\S+) # interogare
[^"]+"\s*
(\d+) # stare
\s+\S+\s+"[^"]*"\s+"
([^"]*) # browser
"
.*
)$/x
) {
my @chunks = split(/ +/, $line);
my $ip = $1;
data mea $ = $2;
my $query = $3;
starea mea $ = 4 $;
my $browser = $5;

push(@date, [$ip, $dată, $interogare, $stare, $browser, $linie]);
}
}

my @sorted = sort {
$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]
} @date;

foreach my $data ( @sorted ) {
print $date->[5];
}

ieșirea 0;

Când rulați acest program, redirecționați „STDOUT”, astfel încât să fie posibil să verificați rezultatul
corectați de la următoarele teste și utilizați utilitarul „timp” al sistemului pentru a verifica totalul
timpul de rulare.

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

0m17.371s real
utilizator 0m15.757s
sys 0m0.592s

Programul a durat puțin peste 17 secunde de ceas de perete. Observați diferitele valori „timp”
ieșiri, este important să folosiți întotdeauna aceeași, și să nu confundați fiecare dintre ele
mijloace.

Timp real scurs
Ora generală, sau ceasul de perete, între momentul în care a fost numit „timp” și momentul în care acesta
încetează. Timpul scurs include atât timpii utilizatorului, cât și timpul de sistem, precum și timpul petrecut
în așteptarea altor utilizatori și procese din sistem. Inevitabil, acesta este cel mai mult
aproximativă a măsurătorilor date.

Timp CPU utilizator
Timpul utilizatorului este cantitatea de timp pe care întregul proces a petrecut în numele utilizatorului
acest sistem execută acest program.

Timp CPU de sistem
Timpul sistemului este cantitatea de timp pe care nucleul însuși a petrecut executând rutine sau
apeluri de sistem, în numele acestui utilizator de proces.

Rulând același proces ca o „Transformare Schwarzian”, este posibil să se elimine
matrice de intrare și de ieșire pentru stocarea tuturor datelor și pentru a lucra direct la intrare
ajunge si el. În caz contrar, codul arată destul de asemănător:

# sort-apache-log-schwarzian

#!/usr/bin/perl -n

folosiți strict;
folosiți avertismente;

imprima

harta $_->[0] =>

fel {
$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]
}
harta [ $_, m/^(
([\w\.\-]+) # client
\s*-\s*-\s*\[
([^]]+) # dată
\]\s*"\w+\s*
(\S+) # interogare
[^"]+"\s*
(\d+) # stare
\s+\S+\s+"[^"]*"\s+"
([^"]*) # browser
"
.*
)$/xo ]

=> <>;

ieșirea 0;

Rulați noul cod pe același fișier jurnal, ca mai sus, pentru a verifica noua oră.

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

0m9.664s real
utilizator 0m8.873s
sys 0m0.704s

Timpul a fost redus la jumătate, ceea ce reprezintă o îmbunătățire respectabilă a vitezei pentru orice standard.
Desigur, este important să verificați că rezultatul este în concordanță cu prima rulare a programului,
aici intervine utilitarul „cksum” al sistemului Unix.

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

BTW. Feriți-vă și de presiunea managerilor care văd că accelerați un program cu 50% din
runtime o dată, doar pentru a primi o solicitare o lună mai târziu pentru a face același lucru din nou (povestea adevărată) -
va trebui doar să subliniezi că ești doar om, chiar dacă ești programator Perl și
o sa vezi ce poti face...

LOGARE


O parte esențială a oricărui proces de dezvoltare bun este gestionarea adecvată a erorilor
mesaje adecvate informative, totuşi există o şcoală de gândire care
sugerează că fișierele jurnal ar trebui să fie flecar, ca și cum lanțul de ieșire neîntreruptă
asigură supravieţuirea programului. Dacă viteza este în vreun fel o problemă, această abordare este
gresit.

O vedere comună este codul care arată cam așa:

logger->debug( „Un mesaj de înregistrare prin proces-id: $$ INC: " . Dumper(\%INC) )

Problema este că acest cod va fi întotdeauna analizat și executat, chiar și atunci când se depanează
nivelul setat în fișierul de configurare de înregistrare este zero. Odata ce depanare() subrutina a fost
introdusă și variabila internă $debug confirmată a fi zero, de exemplu, mesajul
care a fost trimis va fi aruncat și programul va continua. În exemplu
dat, totuși, hash-ul „\%INC” va fi deja descărcat și șirul de mesaj
construit, toate acestea ar putea fi ocolite de o variabilă de depanare la instrucțiune
nivel, astfel:

logger->debug( "Un mesaj de înregistrare prin proces-id: $$ INC: " . Dumper(\%INC) ) dacă $DEBUG;

Acest efect poate fi demonstrat prin configurarea unui script de testare cu ambele forme, inclusiv a
Subrutină „debug()” pentru a emula funcționalitatea tipică „logger()”.

# ifdebug

#!/usr/bin/perl

folosiți strict;
folosiți avertismente;

utilizați Benchmark;
utilizați Data::Dumper;
my $DEBUG = 0;

sub depanare {
my $msg = shift;

dacă ( $DEBUG ) {
printează „DEBUG: $msg\n”;
}
};

timethese(100000, {
'debug' => sub {
debug( „Un mesaj de înregistrare $0 prin codul de proces: $$” . Dumper(\%INC) )
},
'ifdebug' => sub {
debug( „Un mesaj de înregistrare $0 prin codul de proces: $$” . Dumper(\%INC) ) dacă $DEBUG
},
});

Să vedem ce face „Benchmark” din asta:

$> perl ifdebug
Benchmark: sincronizare 100000 de iterații de constantă, sub...
ifdebug: 0 wallclock secunde (0.01 usr + 0.00 sys = 0.01 CPU) @ 10000000.00/s (n=100000)
(avertisment: prea puține iterații pentru o numărare sigură)
depanare: 14 secunde wallclock (13.18 usr + 0.04 sys = 13.22 CPU) @ 7564.30/s (n=100000)

În un caz, codul, care face exact același lucru în ceea ce privește scoaterea oricăruia
informațiile de depanare este în cauză, cu alte cuvinte nimic, durează 14 secunde, iar în
în alt caz, codul durează o sutime de secundă. Pare destul de definitiv. Folosește o
Variabila $DEBUG ÎNAINTE de a apela subrutină, în loc să te bazezi pe smart
funcționalitatea din interiorul acestuia.

Exploatari forestiere if REMEDIERE (constant)
Este posibil să duceți ideea anterioară puțin mai departe, folosind un timp de compilare „DEBUG”
constantă.

# ifdebug-constant

#!/usr/bin/perl

folosiți strict;
folosiți avertismente;

utilizați Benchmark;
utilizați Data::Dumper;
utilizați constantă
DEBUG => 0
;

sub depanare {
if ( DEBUG ) {
my $msg = shift;
printează „DEBUG: $msg\n”;
}
};

timethese(100000, {
'debug' => sub {
debug( „Un mesaj de înregistrare $0 prin codul de proces: $$” . Dumper(\%INC) )
},
'constant' => sub {
debug( „Un mesaj de înregistrare $0 prin ID-ul procesului: $$” . Dumper(\%INC) ) dacă DEBUG
},
});

Rularea acestui program produce următorul rezultat:

$> perl ifdebug-constant
Benchmark: sincronizare 100000 de iterații de constantă, sub...
constantă: 0 secunde wallclock (-0.00 usr + 0.00 sys = -0.00 CPU) @ -7205759403792793600000.00/s (n=100000)
(avertisment: prea puține iterații pentru o numărare sigură)
sub: 14 secunde wallclock (13.09 usr + 0.00 sys = 13.09 CPU) @ 7639.42/s (n=100000)

Constanta „DEBUG” șterge pardoseala chiar și cu variabila $debug, acționând la minus
zero secunde și generează un mesaj „avertisment: prea puține iterații pentru un număr de încredere”.
pe deasupra. Pentru a vedea ce se întâmplă cu adevărat și de ce am avut prea puține iterații când
am crezut că am cerut 100000, putem folosi foarte utilul „B::Deparse” pentru a inspecta noul
cod:

$> perl -MO=Deparse ifdebug-constant

utilizați Benchmark;
utilizați Data::Dumper;
folosește constanta ('DEBUG', 0);
sub depanare {
folosiți avertismente;
utilizați „ref” stricte;
0;
}
folosiți avertismente;
utilizați „ref” stricte;
timethese(100000, {'sub', sub {
depanare „Un mesaj de înregistrare $0 prin ID-ul procesului: $$” . Dumper (\%INC);
}
, „constant”, sub {
0;
}
});
sintaxa constantă ifdebug OK

Ieșirea arată constant() subrutina pe care o testăm fiind înlocuită cu valoarea a
constanta „DEBUG”: zero. Linia de testat a fost complet optimizată departe, și
nu poți deveni mult mai eficient decât atât.

POSTSCRIPT


Acest document a oferit mai multe modalități de identificare și verificare a punctelor fierbinți
dacă modificările au îmbunătățit durata de execuție a codului.

Ca un ultim gând, amintiți-vă că nu este posibil (la momentul scrierii) să produceți a
program util care va rula în timp zero sau negativ și acest principiu de bază poate fi
scris ca: util programe sunt încetini prin însăși definiția lor. Desigur, este posibil
pentru a scrie un program aproape instantaneu, dar nu va face foarte mult, iată un foarte
unul eficient:

$> perl -e 0

Optimizarea mai departe este o treabă pentru „p5p”.

Utilizați perlperf online folosind serviciile onworks.net


Servere și stații de lucru gratuite

Descărcați aplicații Windows și Linux

  • 1
    OfficeFloor
    OfficeFloor
    OfficeFloor oferă inversarea
    controlul cuplajului, cu: - dependenta
    injectare - continuare injectare -
    injecție filet Pentru mai multe informații
    Viziteaza...
    Descărcați OfficeFloor
  • 2
    DivKit
    DivKit
    DivKit este o sursă deschisă bazată pe server
    cadru UI (SDUI). Îți permite
    lansați actualizările provenite de la server la
    diferite versiuni de aplicație. De asemenea, poate fi
    folosit pentru ...
    Descărcați DivKit
  • 3
    subconvertor
    subconvertor
    Utilitate pentru a converti între diverse
    format de abonament. Utilizatori Shadowrocket
    ar trebui să folosească ss, ssr sau v2ray ca țintă.
    Puteți adăuga &remark= la
    HT apreciat de Telegram...
    Descărcați subconvertorul
  • 4
    SPĂLARE
    SPĂLARE
    SWASH este o valoare numerică de uz general
    instrument pentru simularea instabilității,
    nehidrostatic, cu suprafață liberă,
    flux rotaţional şi fenomene de transport
    în apele de coastă ca...
    Descărcați SWASH
  • 5
    VBA-M (arhivat - Acum pe Github)
    VBA-M (arhivat - Acum pe Github)
    Proiectul s-a mutat la
    https://github.com/visualboyadvance-m/visualboyadvance-m
    Caracteristici:Creații de înșelăciune salvează stări multiple
    sistem, acceptă gba, gbc, gb, sgb,
    sgb2Tu...
    Descărcați VBA-M (arhivat - Acum pe Github)
  • 6
    Stacer
    Stacer
    Optimizator și monitorizare de sistem Linux
    Depozitul Github:
    https://github.com/oguzhaninan/Stacer.
    Public: utilizatori finali/desktop. Utilizator
    interfață: Qt. Programare La...
    Descărcați Stacer
  • Mai mult »

Comenzi Linux

Ad