англійськафранцузькаіспанська

Значок OnWorks

perlperf - Інтернет у хмарі

Запустіть perlperf у постачальника безкоштовного хостингу OnWorks через Ubuntu Online, Fedora Online, онлайн-емулятор Windows або онлайн-емулятор MAC OS

Це команда perlperf, яку можна запустити в постачальнику безкоштовного хостингу OnWorks за допомогою однієї з наших численних безкоштовних робочих станцій, таких як Ubuntu Online, Fedora Online, онлайн-емулятор Windows або онлайн-емулятор MAC OS.

ПРОГРАМА:

ІМ'Я


perlperf - Техніки продуктивності та оптимізації Perl

ОПИС


Це вступ до використання методів продуктивності та оптимізації, які можуть бути
використовується з особливим посиланням на програми perl. Хоча багато розробників perl прийшли
з іншими мовами, і можуть використовувати свої попередні знання, де це доречно, є багато
інші люди, яким може бути корисно кілька вказівок на Perl. Якщо ви хочете,
скорочена версія, мабуть, найкраща порада походить від відомого японського самурая,
Міямото Мусасі, який сказав:

«Не займатися марною діяльністю»

В 1645.

ОГЛЯД


Можливо, найпоширенішою помилкою програмістів є спроби оптимізувати свій код
перш ніж програма дійсно зробить щось корисне - це погана ідея. Немає сенсу
наявність надзвичайно швидкої програми, яка не працює. Перше завдання – отримати програму
правильно робити щось корисний, (не кажучи вже про те, щоб тестовий набір повністю заповнений
функціональний), і лише потім розглядати його оптимізацію. Вирішивши оптимізувати існуючі
робочого коду, є кілька простих, але важливих кроків, які слід розглянути, які є внутрішніми
до будь-якого процесу оптимізації.

ONE КРОК БОК
По-перше, вам потрібно встановити базовий час для існуючого коду, який потребує часу
бути надійним і повторюваним. Ймовірно, вам захочеться використати "Порівняльний тест" або
Модулі "Devel::NYTProf" або щось подібне для цього кроку, або, можливо, система Unix
утиліта "час", залежно від того, що підходить. Див. основу цього документа, щоб отримати довший список
модулів порівняльного аналізу та профілювання, а також рекомендовано до прочитання.

ONE КРОК ВПЕРЕД
Далі, вивчивши програму для гарячий плями, (місця, де, здається, працює код
повільно), змініть код з наміром прискорити його роботу. Використання версії
контрольне програмне забезпечення, як-от "підривна діяльність", гарантує, що зміни не є незворотними. Це теж
легко возитися тут і важдатися там – не змінюйте занадто багато за один раз, інакше ви можете
не виявити, який фрагмент коду насправді був повільним.

ІНША КРОК БОК
Недостатньо сказати: «це змусить його працювати швидше», потрібно це перевірити. Повторно запустіть
код під керуванням модулів порівняльного аналізу або профілювання, з першого кроку вище,
і перевірте, що новий код виконав файл то ж завдання in менше час. Збережіть свою роботу і
повторити...

Загальні відомості Вказівки


При розгляді продуктивності важливо пам’ятати, що не існує такої речі, як a
«Золота куля», тому тут немає правил, є лише рекомендації.

Зрозуміло, що вбудований код буде швидшим, ніж виклики підпрограм або методів,
оскільки накладні витрати менше, але недолік цього підходу — менші
обслуговується і забезпечується ціною більшого використання пам'яті - не існує такого поняття, як a
безкоштовний обід. Якщо ви шукаєте елемент у списку, це може бути ефективніше
зберігайте дані в хеш-структурі, а потім просто подивіться, чи є ключ
визначено, а не перебирати весь масив за допомогою grep () наприклад. substr ()
може бути (набагато) швидше ніж grep () але не настільки гнучким, тож у вас є інший компроміс
доступ. Ваш код може містити рядок, виконання якого займає 0.01 секунди, якщо ви
викликати це 1,000 разів, цілком ймовірно, що програма аналізує навіть файли середнього розміру
наприклад, у вас уже є 10-секундна затримка лише в одному місці коду, і якщо ви
викликайте цю лінію 100,000 XNUMX разів, вся ваша програма сповільниться до нестерпного повзання.

Використання підпрограми як частини вашого сортування є потужним способом отримати саме те, що ви хочете,
але зазвичай буде повільніше, ніж вбудований алфавітна "cmp" і числовий Сортування "<=>".
операторів. Можна зробити кілька проходів над вашими даними, створюючи індекси
зробити майбутній сортування більш ефективним і використовувати те, що відомо як "OM" (Orcish
Маневр), щоб заздалегідь кешувати ключі сортування. Пошук у кеш-пам’яті, хоча й гарна ідея, може
сам по собі буде джерелом уповільнення за рахунок застосування подвійного проходу даних - один раз до налаштування
кеш і один раз для сортування даних. Використання "pack()" для вилучення необхідного ключа сортування
у послідовний рядок може бути ефективним способом побудови єдиного рядка для порівняння,
замість використання декількох ключів сортування, що дає можливість використовувати стандартні, написані
у "c" і швидко, функція perl "sort()" на виході і є основою "GRT"
(Перетворення Гутмана Росслера). Деякі комбінації рядків можуть уповільнити "GRT" просто
бути занадто простим складним для його власного блага.

Для додатків, які використовують серверні системи бази даних, стандартний простір імен "DBIx" намагається допомогти
не в останню чергу тому, що це намагається НЕ запитувати базу даних, поки не
останній можливий момент, але завжди читайте документи, які постачаються разом із вибраними бібліотеками.
Серед багатьох проблем, з якими стикаються розробники, які мають справу з базами даних, слід пам’ятати
завжди використовувати заповнювачі "SQL" і розглянути можливість попереднього отримання наборів даних, коли це може бути
виявитися вигідним. Розбиття великого файлу шляхом призначення кількох процесів для аналізу
один файл із використанням "POE", "threads" або "fork" також може бути корисним способом оптимізації
використання вами доступних ресурсів "процесора", хоча ця методика чревата
проблеми з паралельністю і вимагає високої уваги до деталей.

Кожен випадок має конкретне застосування та один або кілька винятків, і їх немає
заміна запуску кількох тестів і визначення того, який метод найкраще підходить для вашого
конкретному середовищі, ось чому написання оптимального коду не є точною наукою, і чому
ми дуже любимо використовувати Perl - TMTOWTDI.

ПОСЛУГИ


Ось кілька прикладів, щоб продемонструвати використання інструментів порівняльного аналізу Perl.

Призначення та Розіменування Змінні.
Я впевнений, що більшість із нас бачили код, який виглядає так (або гірше ніж):

якщо ( $obj->{_ref}->{_myscore} >= $obj->{_ref}->{_yourscore} ) {
...

Цей тип коду може бути справжньою болем на оці для читання, а також дуже чутливим до друкарських помилок,
і набагато зрозуміліше розіменовувати змінну явно. Ми обходимо стороною
питання роботи з методами об'єктно-орієнтованого програмування для інкапсуляції змінної
доступ через методи, доступний лише через об’єкт. Тут ми просто обговорюємо
технічна реалізація вибору та чи впливає це на продуктивність. Ми можемо
Перевірте, чи має ця операція розіменування будь-які накладні витрати, додавши порівняльний код
файл і запуск тесту "Benchmark".

# розіменування

#!/usr/bin/perl

використовувати суворий;
використовувати попередження;

використовувати Benchmark;

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

timethese(1000000, {
'direct' => sub {
мій $x = $ref->{ref}->{_myscore} . $ref->{ref}->{_yourcore} ;
},
'dereference' => sub {
мій $ref = $ref->{ref};
мій $myscore = $ref->{_myscore};
мій $yourscore = $ref->{_yourscore};
мій $x = $myscore . $yourcore;
},
});

Важливо виконувати будь-які вимірювання часу достатню кількість разів, щоб цифри
встановлюються на середньочисельному, інакше кожен цикл буде природним чином коливатися через
зміни в середовищі, щоб зменшити ефект суперечки за ресурси «CPU» та
пропускна здатність мережі, наприклад. Ми можемо виконати наведений вище код протягом мільйона ітерацій
подивіться на вихідний звіт модуля "Benchmark", щоб побачити, який підхід є
найефективніший.

$> розіменування perl

Контроль: хронометраж 1000000 ітерацій разыменування, прямий...
розіменування: 2 секунди настінного годинника (1.59 usr + 0.00 sys = 1.59 CPU) @ 628930.82/s (n=1000000)
прямий: 1 настінний годинник с (1.20 usr + 0.00 sys = 1.20 CPU) @ 833333.33/с (n=1000000)

Різниця очевидна, а підхід розіменування повільніший. Поки це вдалося
виконувати в середньому 628,930 XNUMX разів на секунду під час нашого тесту, прямого підходу
зумів пробігти додатково 204,403 XNUMX рази, на жаль. На жаль, тому що там
є багато прикладів коду, написаного з використанням багаторівневого прямого доступу до змінних, і
зазвичай це жахливо. Однак це трохи швидше. Залишається питання чи
хвилинний приріст насправді коштує напруження очей або втрати ремонтопридатності.

Пошук та замінювати or tr
Якщо у нас є рядок, який потрібно змінити, тоді як регулярний вираз майже завжди буде багато
більш гнучкий, «tr», часто недостатньо використовуваний інструмент, все ще може бути корисним. Один сценарій може бути
замінити всі голосні на інший символ. Рішення регулярного виразу може виглядати так:

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

Альтернатива "tr" може виглядати так:

$str =~ tr/aeiou//

Ми можемо помістити це в тестовий файл, який ми можемо запустити, щоб перевірити, який підхід є найшвидшим,
використовуючи глобальну змінну $STR для призначення змінній "my $str", щоб уникнути Perl
намагаючись оптимізувати будь-яку роботу, помітивши, що вона призначена лише один раз.

# транслітерація регулярного виразу

#!/usr/bin/perl

використовувати суворий;
використовувати попередження;

використовувати Benchmark;

my $STR = "$$-це і те";

timethese( 1000000, {
'sr' => sub { my $str = $STR; $str =~ s/[aeiou]/x/g; повернути $str; },
'tr' => sub { my $str = $STR; $str =~ tr/aeiou//; повернути $str; },
});

Запуск коду дає нам наші результати:

$> perl regex-transliterate

Контроль: хронометраж 1000000 ітерацій sr, tr...
sr: 2 секунди настінного годинника (1.19 usr + 0.00 sys = 1.19 CPU) @ 840336.13/s (n=1000000)
tr: 0 секунд годинника (0.49 usr + 0.00 sys = 0.49 CPU) @ 2040816.33/s (n=1000000)

Версія "tr" є явним переможцем. Одне рішення гнучке, інше швидке - і
програміст має відповідний вибір, що використовувати.

Перевірте документацію "Benchmark", щоб отримати додаткові корисні методи.

ПРОФІЛЮВАННЯ ЗАСОБИ


Трохи більший фрагмент коду надасть те, що може створювати профайлер
більш розширена звітна статистика. У цьому прикладі використовується спрощена програма "wordmatch".
який аналізує заданий вхідний файл і видає короткий звіт про вміст.

# збіг слів

#!/usr/bin/perl

використовувати суворий;
використовувати попередження;

=head1 НАЗВА

filewords - аналіз слів у вхідному файлі

=head1 СИНОПСИС

файлові слова -f вхідна назва файлу [-d]

=head1 ОПИС

Ця програма аналізує дане ім’я файлу, зазначене за допомогою C<-f>, і відображає a
простий аналіз знайдених у ньому слів. Використовуйте перемикач C<-d>, щоб увімкнути
повідомлення про налагодження.

= вирізати

використовувати FileHandle;
використовуйте Getopt::Long;

мій $debug = 0;
мій $file = '';

мій $result = GetOptions (
'debug' => \$debug,
'file=s' => \$файл,
);
die("недійсні аргументи"), якщо $result;

якщо ( -f $file ) {
die("Використання: $0 -f ім'я файлу [-d]");
}
my $FH = FileHandle->new("< $file") або die("неможливо відкрити файл($file): $!");

мої $i_LINES = 0;
мої $i_WORDS = 0;
мій %count = ();

мій @lines = <$FH>;
foreach my $line ( @lines ) {
$i_LINES++;
$рядок =~ s/\n//;
мої @words = split(/ +/, $line);
мій $i_words = скаляр (@words);
$i_WORDS = $i_WORDS + $i_words;
debug("рядок: $i_LINES, що надає $i_words слова: @words");
моє $i_word = 0;
foreach моє $word ( @words ) {
$i_word++;
$count{$i_LINES}{spec} += matches($i_word, $word, '[^a-zA-Z0-9]');
$count{$i_LINES}{only} += відповідає($i_word, $word, '^[^a-zA-Z0-9]+$');
$count{$i_LINES}{cons} += відповідає($i_word, $word, '^[(?i:bcdfghjklmnpqrstvwxyz)]+$');
$count{$i_LINES}{vows} += відповідає($i_word, $word, '^[(?i:aeiou)]+$');
$count{$i_LINES}{caps} += matches($i_word, $word, '^[(AZ)]+$');
}
}

роздрукувати звіт ( %count );

підкладні збіги {
мій $i_wd = shift;
моє $word = зміщення;
мій $regex = shift;
мій $ має = 0;

якщо ( $word =~ /($regex)/ ) {
$має++, якщо $1;
}

debug("слово: $i_wd ".($ має ? 'відповідає' : 'не збігається')." chars: /$regex/");

повернути $ має;
}

підзвіт {
мій % звіт = @_;
мій %повтор;

foreach my $line ( ключі %report ) {
foreach мій $key (ключі %{ $report{$line} } ) {
$rep{$key} += $report{$line}{$key};
}
}

мій $report = qq|
$0 звіт для $file:
рядки у файлі: $i_LINES
слова у файлі: $i_WORDS
слова зі спеціальними (не слівними) символами: $i_spec
слова лише зі спеціальними (не слівними) символами: $i_only
слова лише з приголосними: $i_cons
слова лише з великої літери: $i_caps
слова лише з голосними: $i_vows
|;

повернути $звіт;
}

підналагодження {
моє $message = shift;

якщо ( $debug ) {
print STDERR "DBG: $message\n";
}
}

вихід 0;

Розробник::Дпроф
Цей шановний модуль був де-факто стандартом для профілювання коду Perl більше ніж
десятиліття, але його замінили ряд інших модулів, до яких ми повернулися
21 століття. Хоча вам рекомендується оцінити свій інструмент з кількох
згадані тут і зі списку CPAN на основі цього документа (і в даний час
Devel::NYTProf, здається, є зброєю вибору - дивіться нижче), ми швидко розглянемо
спочатку вихідні дані Devel::DPof, щоб встановити базову лінію для інструментів профілювання Perl. Запустіть
вище програми під керуванням "Devel::DPof" за допомогою перемикача "-d" на команді-
лінія.

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

<...вирізано декілька рядків...>

звіт про збіг слів для perl5db.pl:
рядків у файлі: 9428
слів у файлі: 50243
слів зі спеціальними (неслововими) символами: 20480
слів лише зі спеціальними (неслововими) символами: 7790
слова тільки з приголосними: 4801
слова лише з великої літери: 1316
слова лише з голосними: 1701

"Devel::DPof" створює спеціальний файл, який називається tmon.out за замовчуванням, і цей файл читається
програмою "dprofpp", яка вже встановлена ​​як частина "Devel::DPof"
розповсюдження. Якщо ви закличете "dprofpp" без параметрів, він прочитає файл tmon.out файл у
поточного каталогу та створіть доступний для читання статистичний звіт про запуск вашого
програма. Зауважте, що це може зайняти трохи часу.

$> dprofpp

Загальний час = 2.951677 секунди
Користувач+Системний час = 2.871677 секунд
Ексклюзивні часи
%Time ExclSec CumulS #Виклики с/виклик Csec/c Ім'я
102. 2.945 3.003 251215 0.0000 0.0000 головне:: сірники
2.40 0.069 0.069 260643 0.0000 0.0000 main::debug
1.74 0.050 0.050 1 0.0500 0.0500 головне::звіт
1.04 0.030 0.049 4 0.0075 0.0123 main::BEGIN
0.35 0.010 0.010 3 0.0033 0.0033 Експортер::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 - - Символ::ПОЧАТОК
0.00 - -0.000 1 - - Fcntl::BEGIN
0.00 - -0.000 1 - - Fcntl::bootstrap
0.00 - -0.000 1 - - попередження::BEGIN
0.00 - -0.000 1 - - IO::bootstrap
0.00 - -0.000 1 - - Getopt::Long::ConfigDefaults
0.00 - -0.000 1 - - Getopt::Long::Налаштувати
0.00 - -0.000 1 - - Символ::gensym

"dprofpp" створить досить детальні звіти про діяльність "wordmatch"
програма. Настінний годинник, користувач і система, час знаходяться на початку аналізу та після
це основні стовпці, які визначають звіт. Перевірте документи "dprofpp".
деталі багатьох параметрів, які він підтримує.

Дивіться також «Apache::DPof», який підключає «Devel::DPof» до «mod_perl».

Розробник::Профайлер
Давайте подивимося на ту саму програму, використовуючи інший профайлер: "Devel::Profiler", a
заміна лише для Perl для "Devel::DPof". Використання дуже трохи відрізняється в
що замість використання спеціального прапора "-d:", ви втягуєте "Devel::Profiler" безпосередньо як
модуль за допомогою "-M".

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

<...вирізано декілька рядків...>

звіт про збіг слів для perl5db.pl:
рядків у файлі: 9428
слів у файлі: 50243
слів зі спеціальними (неслововими) символами: 20480
слів лише зі спеціальними (неслововими) символами: 7790
слова тільки з приголосними: 4801
слова лише з великої літери: 1316
слова лише з голосними: 1701

"Devel::Profiler" генерує файл tmon.out, сумісний з "dprofpp"
програму, що зберігає побудову спеціальної програми читання статистичних даних. "dprofpp"
Тому використання ідентично наведеному вище прикладу.

$> dprofpp

Загальний час = 20.984 секунди
Користувач+Системний час = 19.981 секунд
Ексклюзивні часи
%Time ExclSec CumulS #Виклики с/виклик Csec/c Ім'я
49.0 9.792 14.509 251215 0.0000 0.0001 головне:: сірники
24.4 4.887 4.887 260643 0.0000 0.0000 main::debug
0.25 0.049 0.049 1 0.0490 0.0490 головне::звіт
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::Файл::новий
0.00 0.000 0.000 1 0.0000 0.0000 IO::Handle::new
0.00 0.000 0.000 1 0.0000 0.0000 Символ::gensym
0.00 0.000 0.000 1 0.0000 0.0000 IO::File::open

Цікаво, що ми отримуємо дещо інші результати, в основному через алгоритм
який формує звіт відрізняється, навіть якщо вихідний формат нібито був
ідентичні. Час, який минув, користувач і система чітко показують час, який витрачено
"Devel::Profiler", щоб виконати власний запуск, але списки стовпців виглядають точнішими
чимось ніж ті, які ми мали раніше від "Devel::DPof". Показник 102%.
зник, наприклад. Тут ми повинні використовувати інструменти, які є в нашому розпорядженні, і
визнайте їх плюси і мінуси, перш ніж використовувати їх. Цікаво, що номери дзвінків за
кожна підпрограма ідентична в двох звітах, це відсотки, які відрізняються. Як
автор «Devel::Proviler» пише:

...виконання набору тестів HTML::Template під Devel::DPof показує вихід()
НЕ займає часу, але Devel::Profiler показує, що близько 10% часу знаходиться у output().
Я не знаю, кому вірити, але мій нутро підказує мені, що з чимось не так
Розробник::Дпроф. HTML::Template::output() — це велика процедура, яка потрібна
кожен тест. У будь-якому випадку, щось потрібно виправити.

YMMV.

Дивіться також «Devel::Apache::Profiler», який підключає «Devel::Profiler» до «mod_perl».

Розробник::МалийПроф
Профайлер "Devel::SmallProf" перевіряє час виконання вашої програми Perl і створює
Порядковий список, щоб показати, скільки разів викликано кожен рядок і як довго кожен рядок
взяли на виконання. Він викликається шляхом надання знайомого прапора "-d" Perl під час виконання.

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

<...вирізано декілька рядків...>

звіт про збіг слів для perl5db.pl:
рядків у файлі: 9428
слів у файлі: 50243
слів зі спеціальними (неслововими) символами: 20480
слів лише зі спеціальними (неслововими) символами: 7790
слова тільки з приголосними: 4801
слова лише з великої літери: 1316
слова лише з голосними: 1701

"Devel::SmallProf" записує його вихід у файл з назвою малопроф.вих, за замовчуванням. The
формат файлу виглядає так:

:

Після завершення роботи програми вихідні дані можуть бути перевірені та відсортовані за допомогою будь-якого стандарту
утиліти фільтрації тексту. Може бути достатньо чогось на кшталт наступного:

$> cat smallprof.out | grep \d*: | сортування -k3 | так | голова -n20

251215 1.65674 7.68000 75: якщо ( $word =~ /($regex)/ ) {
251215 0.03264 4.40000 79: debug("word: $i_wd ".($has ? ' matches' :
251215 0.02693 4.10000 81: повернення $ має;
260643 0.02841 4.07000 128: if ( $debug ) {
260643 0.02601 4.04000 126: моє $message = shift;
251215 0.02641 3.91000 73: мій $ має = 0;
251215 0.03311 3.71000 70: my $i_wd = shift;
251215 0.02699 3.69000 72: мій $regex = shift;
251215 0.02766 3.68000 71: моє $word = 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: мої $i_cons = збіги ($i_word, $word,
50243 0.48837 0.88000 63: $count{$i_LINES}{caps} =
50243 0.00516 0.88000 58: мої $i_caps = відповідають($i_word, $word, '^[(A-
50243 0.00631 0.81000 54: моя $i_spec = відповідає ($i_word, $word, '[^a-
50243 0.00496 0.80000 57: мої $i_vows = збіги ($i_word, $word,
50243 0.00688 0.80000 53: $i_word++;
50243 0.48469 0.79000 62: $count{$i_LINES}{only} =
50243 0.48928 0.77000 60: $count{$i_LINES}{vows} =

50243 0.00683 0.75000 55: мій $i_only = відповідає($i_word, $word, '^[^a-
Ви відразу можете побачити дещо інший фокус модулів профілювання підпрограм,
і ми починаємо бачити, який саме рядок коду займає найбільше часу. Цей рядок регулярного виразу
наприклад, виглядає трохи підозріло. Пам'ятайте, що ці інструменти повинні бути
якщо використовувати разом, не існує єдиного найкращого способу профілювання вашого коду, вам потрібно використовувати найкращий
інструменти для роботи.

Дивіться також «Apache::SmallProf», який підключає «Devel::SmallProf» до «mod_perl».

Розробник::FastProf
"Devel::FastProf" - це ще один профайлер рядків Perl. Це було написано з метою отримання
швидший профайлер рядків, ніж це можливо з, наприклад, "Devel::SmallProf", тому що це
написано на «С». Щоб використовувати "Devel::FastProf", введіть аргумент "-d" до Perl:

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

<...вирізано декілька рядків...>

звіт про збіг слів для perl5db.pl:
рядків у файлі: 9428
слів у файлі: 50243
слів зі спеціальними (неслововими) символами: 20480
слів лише зі спеціальними (неслововими) символами: 7790
слова тільки з приголосними: 4801
слова лише з великої літери: 1316
слова лише з голосними: 1701

"Devel::FastProf" записує статистику у файл fastprof.out у поточному каталозі.
Вихідний файл, який можна вказати, можна інтерпретувати за допомогою "fprofpp"
програму командного рядка.

$> fprofpp | голова -n20

# fprofpp формат виведення:
# ім'я файлу: кількість часу рядка: джерело
wordmatch:75 3.93338 251215: if ( $word =~ /($regex)/ ) {
wordmatch:79 1.77774 251215: debug("word: $i_wd ".($has ? 'matches' : 'ne збігається')." chars: /$regex/");
wordmatch:81 1.47604 251215: повертає $has;
wordmatch:126 1.43441 260643: my $message = shift;
wordmatch:128 1.42156 260643: if ( $debug ) {
wordmatch:70 1.36824 251215: my $i_wd = shift;
wordmatch:71 1.36739 251215: my $word = shift;
wordmatch:72 1.35939 251215: мій $regex = shift;

Відразу ми бачимо, що кількість викликів кожного рядка ідентична
вихід "Devel::SmallProf", і послідовність лише трохи відрізняється на основі
впорядкування кількості часу, необхідного для виконання кожного рядка, "if ( $debug ) { " і "мій
$message = shift;", наприклад. Різниця в фактичних записах часу може бути в
алгоритм, що використовується внутрішньо, або це може бути через обмеження системних ресурсів або
суперечка.

Дивіться також профіль DBIx::Profile, який профільуватиме запити до бази даних, що виконуються під "DBIx::*"
простір імен.

Розробник::NYTProf
"Devel::NYTProf" - це наступний покоління профайлера коду Perl, виправивши багато недоліків у
інші інструменти та реалізацію багатьох цікавих функцій. Перш за все, його можна використовувати як а
лінія профайлер, а блок або підпрограма профайлер, усе одразу. Він також може використовувати під-
мікросекундна (100 нс) роздільна здатність у системах, які забезпечують "clock_gettime()". Це може бути
запускається та зупиняється навіть програмою, що профілюється. Це однорядковий запис у профілі
програми "mod_perl". Він написаний буквою "c" і, ймовірно, є найшвидшим профайлером
доступний для Perl. Список прохолоди можна продовжувати. Досить цього, подивимося, як
це працює - просто використовуйте знайомий перемикач "-d", щоб підключити його і запустити код.

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

звіт про збіг слів для perl5db.pl:
рядків у файлі: 9427
слів у файлі: 50243
слів зі спеціальними (неслововими) символами: 20480
слів лише зі спеціальними (неслововими) символами: 7790
слова тільки з приголосними: 4801
слова лише з великої літери: 1316
слова лише з голосними: 1701

"NYTProf" створить базу даних звітів у файлі nytprof.out за замовчуванням. Людський
Читані звіти можна створювати звідси за допомогою наданого «nytprofhtml» (HTML
вихід) і програми "nytprofcsv" (вивід CSV). Ми використовували систему Unix "html2text"
утиліта для перетворення nytprof/index.html файл для зручності тут.

$> html2text nytprof/index.html

Індекс профілю ефективності
Для збігу слів
Запуск у пт 26 вересня 13:46:39 2008 року
Повідомлено в пт, 26 вересня 13:47:23 2008 року

15 найкращих підпрограм – упорядковані за ексклюзивним часом
|Виклики |P |F |Включно|Виключно|Підпрограма |
| | | |Час |Час | |
|251215|5 |1 |13.09263 |10.47692 |основний:: |сірники |
|260642|2 |1 |2.71199 |2.71199 |основний:: |налагодження |
|1 |1 |1 |0.21404 |0.21404 |основний:: |звіт |
|2 |2 |2 |0.00511 |0.00511 |XSLoader:: |завантаження (xsub) |
|14 |14|7 |0.00304 |0.00298 |Експортер:: |імпорт |
|3 |1 |1 |0.00265 |0.00254 |Експортер:: |як_важкий |
|10 |10|4 |0.00140 |0.00140 |vars:: |імпорт |
|13 |13|1 |0.00129 |0.00109 |постійна:: |імпорт |
|1 |1 |1 |0.00360 |0.00096 |FileHandle:: |імпорт |
|3 |3 |3 |0.00086 |0.00074 |попередження::реєстр::|імпорт |
|9 |3 |1 |0.00036 |0.00036 |суворий:: |розряди |
|13 |13|13|0.00032 |0.00029 |суворий:: |імпорт |
|2 |2 |2 |0.00020 |0.00020 |попередження:: |імпорт |
|2 |1 |1 |0.00020 |0.00020 |Getopt::Long:: |ParseOptionSpec|
|7 |7 |6 |0.00043 |0.00020 |суворий:: |неімпорт |

Для отримання додаткової інформації див. повний список із 189 підпрограм.

У першій частині звіту вже наведено критичну інформацію щодо чого
підпрограми використовують найбільше часу. Далі наводить деяку статистику щодо джерела
файли профільовані.

Файли вихідного коду – упорядковані за ексклюзивним часом, а потім за назвою
|Stmts |Ексклюзив|Сер. |Звіти |Вихідний файл |
| |Час | | | |
|2699761|15.66654 |6e-06 |рядок . блок . під|збіг слів |
|35 |0.02187 |0.00062|рядок . блок . sub|IO/Handle.pm |
|274 |0.01525 |0.00006|рядок . блок . sub|Getopt/Long.pm |
|20 |0.00585 |0.00029|рядок . блок . sub|Fcntl.pm |
|128 |0.00340 |0.00003|рядок . блок . sub|Exporter/Heavy.pm |
|42 |0.00332 |0.00008|рядок . блок . sub|IO/File.pm |
|261 |0.00308 |0.00001|рядок . блок . sub|Exporter.pm |
|323 |0.00248 |8e-06 |рядок . блок . sub|constant.pm |
|12 |0.00246 |0.00021|рядок . блок . sub|File/Spec/Unix.pm |
|191 |0.00240 |0.00001|рядок . блок . sub|vars.pm |
|77 |0.00201 |0.00003|рядок . блок . sub|FileHandle.pm |
|12 |0.00198 |0.00016|рядок . блок . sub|Carp.pm |
|14 |0.00175 |0.00013|рядок . блок . sub|Symbol.pm |
|15 |0.00130 |0.00009|рядок . блок . sub|IO.pm |
|22 |0.00120 |0.00005|рядок . блок . sub|IO/Seekable.pm |
|198 |0.00085 |4e-06 |рядок . блок . sub|warnings/register.pm|
|114 |0.00080 |7e-06 |рядок . блок . sub|strict.pm |
|47 |0.00068 |0.00001|рядок . блок . sub|warnings.pm |
|27 |0.00054 |0.00002|рядок . блок . sub|overload.pm |
|9 |0.00047 |0.00005|рядок . блок . sub|SelectSaver.pm |
|13 |0.00045 |0.00003|рядок . блок . sub|File/Spec.pm |
|2701595|15.73869 | |Усього |
|128647 |0.74946 | |середній |
| |0.00201 |0.00003|Медіана |
| |0.00121 |0.00003|Відхилення |

Звіт підготував профайлер Perl NYTProf 2.03, розроблений Тімом Бансом і
Адам Каплан.

На даний момент, якщо ви використовуєте HTML звіту, ви можете натиснути різні посилання на
розглянути кожну підпрограму і кожен рядок коду. Тому що ми використовуємо текст
звіти тут, і є цілий каталог, повний звітів, створених для кожного вихідного файлу,
ми просто відобразимо частину відповідного wordmatch-line.html файл, достатній для
дайте уявлення про те, який результат ви можете очікувати від цього класного інструменту.

$> html2text nytprof/wordmatch-line.html

Профіль продуктивності -- -блоковий перегляд-.-лінії перегляд-.-під перегляд-
Для збігу слів
Запуск у пт 26 вересня 13:46:39 2008 року
Повідомлено в пт, 26 вересня 13:47:22 2008 року

Файл відповідності слів

Підпрограми -- упорядковані за винятковим часом
|Виклики |P|F|Включно|Виключно|Підпрограма |
| | | |Час |Час | |
|251215|5|1|13.09263 |10.47692 |main::|matches|
|260642|2|1|2.71199 |2.71199 |основний::|налагодження |
|1 |1|1|0.21404 |0.21404 |основний::|звіт |
|0 |0|0|0 |0 |основний::|ПОЧАТОК |

|Лінія|Стмц.|Ексклюзив|Сер. |Код |
| | |Час | | |
|1 | | | |#!/usr/bin/perl |
|2 | | | | |
| | | | | використовувати суворий; |
|3 |3 |0.00086 |0.00029|# витратив 0.00003s на 1 виклик до strict:: |
| | | | |імпорт |
| | | | |використання попереджень; |
|4 |3 |0.01563 |0.00521|# витратив 0.00012с на 1 виклик попереджень:: |
| | | | |імпорт |
|5 | | | | |
|6 | | | |=голова1 НАЗВА |
|7 | | | | |
|8 | | | |filewords - аналіз слів у вхідному файлі |
<...відрізок...>
|62 |1 |0.00445 |0.00445|роздрукувати звіт( %count ); |
| | | | |# витратив 0.21404с на 1 виклик до main::report|
|63 | | | | |
| | | | |# витратив 23.56955с (10.47692+2.61571) протягом |
| | | | |main::matches, який був викликаний 251215 разів, |
| | | | |сер. 0.00005 с/дзвінок: # 50243 разів |
| | | | |(2.12134+0.51939s) у рядку 57 збігу слів, середнє|
| | | | |0.00005 с/виклик # 50243 рази (2.17735+0.54550 с) |
|64 | | | |у рядку 56 узгодження слів, середнє значення 0.00005s/виклик # |
| | | | |50243 разів (2.10992+0.51797s) у рядку 58 |
| | | | |відповідність слів, середнє значення 0.00005 с/виклик # 50243 разів |
| | | | |(2.12696+0.51598s) у рядку 55 збігу слів, середнє|
| | | | |0.00005 с/виклик # 50243 рази (1.94134+0.51687 с) |
| | | | |у рядку 54 узгодження слів, середнє значення 0.00005 с/виклик |
| | | | |підпорядкування { |
<...відрізок...>
|102 | | | | |
| | | | |# витратив 2.71199 секунд у межах main::debug, який був |
| | | | |дзвінків 260642 разів, середнє значення 0.00001s/дзвінок: # |
| | | | |251215 разів (2.61571+0с) за основним::матчі на |
|103 | | | |рядок 74 збігу слів, середнє значення 0.00001 с/виклик # 9427 |
| | | | |раз (0.09628+0с) у рядку 50 збігу слів, середнє|
| | | | |0.00001 с/дзвінок |
| | | | |підналагодження { |
|104 |260642|0.58496 |2e-06 |my $message = shift; |
|105 | | | | |
|106 |260642|1.09917 |4e-06 |if ( $debug ) { |
|107 | | | |друк STDERR "DBG: $message\n"; |
|108 | | | |} |
|109 | | | |} |
|110 | | | | |
|111 |1 |0.01501 |0.01501|вихід 0; |
|112 | | | | |

Там купа дуже корисної інформації - це, здається, шлях вперед.

Дивіться також «Devel::NYTProf::Apache», який підключає «Devel::NYTProf» до «mod_perl».

СОРТУВАННЯ


Модулі Perl — не єдині інструменти, які мають у своєму розпорядженні аналітики продуктивності системи
такі інструменти, як "час", не слід ігнорувати, як показує наступний приклад, де ми беремо a
швидкий погляд на сортування. Про ефективність написано багато книг, тез і статей
алгоритми сортування, і тут не місце повторювати таку роботу, є кілька хороших
модулі сортування, які також заслуговують на увагу: "Sort::Maker", "Sort::Key" пружина для
розуму. Проте все ще можна зробити деякі спостереження щодо певних особливостей Perl
інтерпретації з питань, що стосуються сортування наборів даних, і наведіть приклад або два з
щодо того, як сортування великих обсягів даних може вплинути на продуктивність. По-перше, часто
При сортуванні великих обсягів даних можна спробувати зменшити кількість даних
налаштований для роботи, і в багатьох випадках "grep()" може бути досить корисним як простий фільтр:

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

Подібна команда може значно зменшити обсяг матеріалу для фактичного сортування
в першу чергу, і не слід занадто легковажно нехтувати виключно на основі його
простота. Принцип «ПОЦІЛЮВКУ» занадто часто ігнорується - у наступному прикладі використовується
проста системна утиліта «час» для демонстрації. Давайте розглянемо реальний приклад
для сортування вмісту великого файлу підійде файл журналу Apache. Цей має понад a
чверть мільйона рядків, розміром 50 М, і його фрагмент виглядає так:

# файл журналу

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 (сумісний; 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 (сумісний; 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- США; 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 (сумісний; 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 (сумісний; 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 (сумісний; Konqueror/3.4; Linux) KHTML/3.4.0 (наприклад, 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 (сумісний; Konqueror/3.4; Linux) KHTML/3.4.0 (наприклад, Gecko)"
debora.to.isac.cnr.it - ​​- [08/Feb/2007:13:03:58 +0000] "GET /favicon.ico HTTP/1.1" 404 209 "-" "Mozilla/5.0 (сумісний; Konqueror/ 3.4; Linux) KHTML/3.4.0 (наприклад, 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 (сумісний; 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 (сумісний; 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 (сумісний; MSIE 6.0; Windows NT CLR5.1; .NET. .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 (сумісний; 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 Profile/MIDP -2.0 Конфігурація/CLDC-1.1"

Конкретним завданням тут є сортування 286,525 XNUMX рядків цього файлу за кодом відповіді, запитом,
Веб-переглядач, URL-адреса переходу та, нарешті, дата. Одним із рішень може бути використання наступного коду,
який перебирає файли, задані в командному рядку.

# sort-apache-log

#!/usr/bin/perl -n

використовувати суворий;
використовувати попередження;

мої @data;

ЛІНІЯ:
поки ( <> ) {
моя $line = $_;
Якщо (
$рядок =~ м/^(
([\w\.\-]+) # клієнт
\s*-\s*-\s*\[
([^]]+) # дата
\]\s*"\w+\s*
(\S+) # запит
[^"]+"\s*
(\d+) # статус
\s+\S+\s+"[^"]*"\s+"
([^"]*) # браузер
"
.*
)$/х
) {
мій @chunks = split(/ +/, $line);
мій $ip = $1;
моя $date = $2;
мій $query = $3;
мій $status = $4;
мій $браузер = $5;

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

мій @sorted = сортувати {
$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]
} @дані;

foreach мої $data ( @sorted ) {
надрукувати $data->[5];
}

вихід 0;

Під час запуску цієї програми переспрямуйте "STDOUT", щоб можна було перевірити вихід
виправте з наступних тестових запусків і скористайтеся системною утилітою «час», щоб перевірити загальне значення
час виконання.

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

фактично 0м17.371с
користувач 0m15.757s
sys 0m0.592s

Запуск програми зайняв трохи більше 17 секунд на стінному годиннику. Зверніть увагу на різні значення "часу"
вихідних даних, важливо завжди використовувати один і той самий і не плутати кожен із них
засоби.

Минув у реальному часі
Загальний, або настінний, час між тим, коли було викликано «час», і коли він був викликаний
припиняється. Час, що минув, включає час користувача та системи, а також витрачений час
очікування інших користувачів і процесів у системі. Неминуче, це найбільше
приблизні наведені виміри.

Час процесора користувача
Час користувача — це кількість часу, на який весь процес витрачається від імені користувача
ця система виконує цю програму.

Системний процесорний час
Системний час — це кількість часу, яке саме ядро ​​витратило на виконання підпрограм, або
системні виклики від імені користувача цього процесу.

Виконуючи цей самий процес, як «перетворення Шварца», можна усунути
вхідні та вихідні масиви для зберігання всіх даних і роботи з введенням безпосередньо як вони
надходить теж. В іншому випадку код виглядає досить схожим:

# sort-apache-log-schwarzian

#!/usr/bin/perl -n

використовувати суворий;
використовувати попередження;

друк

карта $_->[0] =>

сортувати {
$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]
}
карта [ $_, м/^(
([\w\.\-]+) # клієнт
\s*-\s*-\s*\[
([^]]+) # дата
\]\s*"\w+\s*
(\S+) # запит
[^"]+"\s*
(\d+) # статус
\s+\S+\s+"[^"]*"\s+"
([^"]*) # браузер
"
.*
)$/xo ]

=> <>;

вихід 0;

Запустіть новий код у тому самому файлі журналу, що й вище, щоб перевірити новий час.

$> час ./sort-apache-log-schwarzian logfile > out-schwarz

фактично 0м9.664с
користувач 0m8.873s
sys 0m0.704s

Час скорочено вдвічі, що є поважним підвищенням швидкості за будь-якими стандартами.
Природно, важливо перевірити, чи відповідає результат першого запуску програми,
ось тут на допомогу приходить системна утиліта Unix "cksum".

$> cksum out-sort out-schwarz
3044173777 52029194 розсорт
3044173777 52029194 поза шварц

BTW. Також остерігайтеся тиску з боку менеджерів, які бачать, що ви прискорюєте програму на 50%.
час виконання один раз, щоб отримати запит через місяць, щоб зробити те ж саме ще раз (правдива історія) -
вам просто доведеться вказати, що ви всього лише людина, навіть якщо ви програміст на Perl, і
ти побачиш, що ти можеш зробити...

ВХІД


Важливою частиною будь-якого хорошого процесу розробки є відповідна обробка помилок
належним чином інформативні повідомлення, однак існує школа думки, яка
передбачає, що файли журналу повинні бути розмовний, ніби ланцюжок безперервного виходу якось
забезпечує виживання програми. Якщо швидкість в будь-якому випадку є проблемою, цей підхід є
неправильно

Поширеним є код, який виглядає приблизно так:

logger->debug( "Повідомлення журналу через ідентифікатор процесу: $$ INC: " . Dumper(\%INC) )

Проблема в тому, що цей код завжди буде аналізуватися і виконуватися, навіть коли налагодження
рівень, встановлений у файлі конфігурації журналу, дорівнює нулю. Одного разу відлагоджувати() була підпрограма
введено, і внутрішня змінна $debug підтвердилася як нульова, наприклад, повідомлення
Надіслана інформація буде відхилена, а програма продовжиться. У прикладі
враховуючи, що хеш "\%INC" вже буде скинуто, а рядок повідомлення
сконструйований, всю роботу яких можна було б обійти за допомогою змінної налагодження в операторі
рівень, наприклад:

logger->debug( "Повідомлення журналу через ідентифікатор процесу: $$ INC: " . Dumper(\%INC) ) if $DEBUG;

Цей ефект можна продемонструвати, налаштувавши тестовий сценарій з обома формами, включаючи a
Підпрограма "debug()" для емуляції типової функціональності "logger()".

# ifdebug

#!/usr/bin/perl

використовувати суворий;
використовувати попередження;

використовувати Benchmark;
використовувати Data::Dumper;
мій $DEBUG = 0;

підналагодження {
мій $msg = shift;

якщо ( $DEBUG ) {
print "DEBUG: $msg\n";
}
};

timethese(100000, {
'debug' => sub {
debug( "Повідомлення журналу $0 через ідентифікатор процесу: $$" . Dumper(\%INC) )
},
'ifdebug' => sub {
debug( "Повідомлення журналу $0 через ідентифікатор процесу: $$" . Dumper(\%INC) ) якщо $DEBUG
},
});

Давайте подивимося, що "Benchmark" робить із цього:

$> perl ifdebug
Контроль: хронометраж 100000 XNUMX ітерацій константи, під...
ifdebug: 0 секунд годинника (0.01 usr + 0.00 sys = 0.01 CPU) @ 10000000.00/с (n=100000)
(попередження: занадто мало ітерацій для надійного підрахунку)
налагодження: 14 секунд годинника (13.18 usr + 0.04 sys = 13.22 CPU) @ 7564.30/с (n=100000)

В одному випадку код, який виконує те саме, що й виводить будь-який
налагодження інформації стосується, іншими словами нічого, займає 14 секунд, а в
в іншому випадку код займає одну соту секунди. Виглядає досить остаточно. Використовуйте a
Змінна $DEBUG ПЕРЕД викликом підпрограми, замість того, щоб покладатися на smart
функціональність всередині нього.

Запис if DEBUG (постійна)
Попередню ідею можна трохи розширити, використовуючи час компіляції "DEBUG"
постійний.

# константа ifdebug

#!/usr/bin/perl

використовувати суворий;
використовувати попередження;

використовувати Benchmark;
використовувати Data::Dumper;
використовувати постійний
НАЛАДЖЕННЯ => 0
;

підналагодження {
if ( DEBUG ) {
мій $msg = shift;
print "DEBUG: $msg\n";
}
};

timethese(100000, {
'debug' => sub {
debug( "Повідомлення журналу $0 через ідентифікатор процесу: $$" . Dumper(\%INC) )
},
'constant' => sub {
debug( "Повідомлення журналу $0 через ідентифікатор процесу: $$" . Dumper(\%INC) ) якщо DEBUG
},
});

Запуск цієї програми дає такий вихід:

$> perl ifdebug-constant
Контроль: хронометраж 100000 XNUMX ітерацій константи, під...
константа: 0 секунд годинника (-0.00 usr + 0.00 sys = -0.00 CPU) @ -7205759403792793600000.00/с (n=100000)
(попередження: занадто мало ітерацій для надійного підрахунку)
під: 14 секунд настінного годинника (13.09 usr + 0.00 sys = 13.09 CPU) @ 7639.42/с (n=100000)

Константа "DEBUG" стирає підлогу навіть із змінною $debug, фіксуючи значення мінус
нуль секунд і генерує повідомлення «попередження: занадто мало ітерацій для надійного підрахунку».
в угоду. Щоб побачити, що насправді відбувається, і чому у нас було занадто мало ітерацій, коли
ми думали, що попросили 100000 XNUMX, ми можемо використовувати дуже корисний "B::Deparse", щоб перевірити новий
Код:

$> perl -MO=Видалити ifdebug-constant

використовувати Benchmark;
використовувати Data::Dumper;
використовувати константу ('DEBUG', 0);
підналагодження {
використовувати попередження;
використовувати строгі «посилання»;
0;
}
використовувати попередження;
використовувати строгі «посилання»;
timethese(100000, {'sub', sub {
debug "Повідомлення журналу $0 через ідентифікатор процесу: $$" . Самоскид (\%INC);
}
, 'constant', sub {
0;
}
});
ifdebug-constant синтаксис OK

Вихід показує константа() підпрограма, яку ми тестуємо, замінюється значенням
константа "DEBUG": нуль. Лінія, яка підлягає тестуванню, була повністю оптимізована, і
ви не можете бути набагато ефективнішим, ніж це.

ПОСТКРИПТ


У цьому документі передбачено кілька способів виявлення та перевірки гарячих точок
чи якісь зміни покращили час виконання коду.

На завершення пам’ятайте, що (на момент написання) неможливо створити a
корисна програма, яка буде працювати за нульовий або від'ємний час, і цей основний принцип може бути
написано як: корисний програми він має сповільнювати за самим їх визначенням. Звичайно, можливо
щоб написати майже миттєву програму, але це не буде робити дуже багато, ось дуже
ефективний:

$> perl -e 0

Подальша оптимізація - це робота для "p5p".

Використовуйте perlperf онлайн за допомогою служб onworks.net


Безкоштовні сервери та робочі станції

Завантажте програми для Windows і Linux

  • 1
    iReport-Designer для JasperReports
    iReport-Designer для JasperReports
    ПРИМІТКА. Підтримка iReport/Jaspersoft Studio
    Оголошення: починаючи з версії 5.5.0,
    Офіційною буде студія Jaspersoft
    дизайн клієнта для JasperReports. iReport
    буде ...
    Завантажте iReport-Designer для JasperReports
  • 2
    PostInstallerF
    PostInstallerF
    PostInstallerF встановить усі файли
    програмне забезпечення, яке Fedora Linux та інші
    не включає за замовчуванням після
    запуск Fedora вперше. Його
    легко для ...
    Завантажте PostInstallerF
  • 3
    страйк
    страйк
    Проект strace перенесено в
    https://strace.io. strace is a
    діагностика, налагодження та інструктаж
    трасування простору користувача для Linux. Його використовують
    стежити за...
    Завантажити strace
  • 4
    gMKVEExtractGUI
    gMKVEExtractGUI
    Графічний інтерфейс для утиліти mkvextract (частина
    MKVToolNix), який включає більшість (if
    не всі) функціональність mkvextract і
    утиліти mkvinfo. Написано на C#NET 4.0,...
    Завантажте gMKVExtractGUI
  • 5
    Бібліотека JasperReports
    Бібліотека JasperReports
    Бібліотека JasperReports – це
    найпопулярніший у світі відкритий код
    бізнес-аналітика та звітність
    двигун. Він повністю написаний на Java
    і воно здатне...
    Завантажте бібліотеку JasperReports
  • 6
    Книги Фраппе
    Книги Фраппе
    Frappe Books є безкоштовним і відкритим вихідним кодом
    програмне забезпечення для настільного бухгалтерського обліку
    простий і добре розроблений для використання
    малий бізнес і фрілансери. Це...
    Завантажте книги про фраппе
  • Детальніше »

Команди Linux

Ad