предварительно скомпилированный Perl вопрос регулярных выражений - PullRequest
2 голосов
/ 04 декабря 2009

Действительно ли я получаю какую-либо выгоду от выполнения следующих действий (в отличие от простого помещения фактического регулярного выражения вместо $ {pcr} в обоих операторах if)? (много больше строк в реальном наборе данных, но только с использованием DATA, например.

my $defs = 0;
my $tests = 0;
my $pcr = qr/\s*[\/\\]?\s*/;
while (<DATA>)
{
    $defs   = ($1 ? 0 : 1) if /<(${pcr})definitions/;
    $tests  = ($1 ? 0 : 1) if /<(${pcr})tests/;
    print "defs: $defs\ntests: $tests\n\n";
}

__DATA__
<what>
</what>
<definitions>
<one />
</definitions>
<tests>
<two />
<three />
</tests>

Ответы [ 2 ]

5 голосов
/ 04 декабря 2009

Выполнение некоторых тестов по сравнению с вашим исходным примером, примером без PCR, и другим примером, где два различных PCR используются для definitions и tests, которые определены вне цикла, я получаю следующие результаты для полумиллиона итерации на моей машине:

               Rate     no_pcr       orig pcr_before
no_pcr     130208/s         --        -1%        -5%
orig       131579/s         1%         --        -4%
pcr_before 137741/s         6%         5%         --

Таким образом, может показаться, что выгоды либо нет, либо она очень мала.

1 голос
/ 04 декабря 2009

Использование perl 'times' для получения значений времени процессора до и после следующих циклов показывает мне, что по какой-то причине предварительно скомпилированная версия регулярного выражения фактически на 33% медленнее, чем встроенное регулярное выражение. Я дважды сопоставил регулярные выражения, чтобы быть близким к коду примера и предотвратить любую загадочную оптимизацию perl во время циклов.

for (1..$num_runs) {
   $test_string =~ $pcr;
   $test_string =~ $pcr;
}

и

for(1..$num_runs) {
   $test_string =~ m/\s*[\/\\]?\s*/;
   $test_string =~ m/\s*[\/\\]?\s*/;
}

С $num_runs = 10000000 и $pcr и $test_string:

my $pcr = qr/\s*[\/\\]?\s*/;
my $test_string = '<what>';

Время процессора после нахождения дельты и усреднения было:

------------------------------
Precompiled regex:
------------------------------
      user : 0.0000040190
    system : 0.0000000010

------------------------------
Inline regex:
------------------------------
      user : 0.0000030580
    system : 0.0000000000

Я не использовал Perl Benchmark.pm по личным причинам. Я видел, что это дает явно неправильные числа, и, хотя они были минимальными, сравнительный анализ не имеет смысла, если у вас есть числа, которым вы не можете доверять. Этим цифрам я могу доверять, хотя тесты, которые я тестировал, могут потребовать переоценки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...