2009-12-04 6 views
2

Ai-je vraiment obtenir un avantage de faire ce qui suit (au lieu de simplement mettre la regex en place du $ {} pcr dans les deux cas des déclarations)? (Beaucoup plus de lignes sont les données réelles établies mais juste en utilisant des données par exemple.perl question précompilés regex

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> 
+1

Que se passe lorsque vous référence vous-même? –

+0

Je me demandais en général vraiment que je ne sais pas grand-chose à propos de pré compilé regex en Perl, me semble que depuis votre mise à l'expression rationnelle précompilé dans une autre déclaration regex tout doit se compilé à nouveau de toute façon. – user105033

+0

Ouais. Je me demande comment on pourrait trouver une chose pareille! –

Répondre

5

l'exécution de certains points de repère votre exemple original, un exemple sans PCR, et un autre exemple où deux sont utilisés de PCR différentes pour definitions et tests , qui sont définies en dehors de la boucle, je reçois les résultats suivants pour un demi-million d'itérations sur ma machine.

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

il semblerait que ce soit il n'y a aucun avantage, ou l'avantage est très faible

1

En utilisant les temps de 'pour obtenir les temps de CPUs de Perl avant et après les boucles suivantes me montre que, pour une raison quelconque, la version pré-compilée regex est en fait environ 33% plus lent que le regex en ligne. J'ai fait le regex match deux fois pour être proche de l'exemple de code et pour empêcher toute optimisation Perl mystérieuse à travers les boucles.

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

et

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

Avec $num_runs étant 10000000 et $pcr et $test_string étant les suivantes:

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

Les temps cpu après avoir trouvé le delta et la moyenne étaient:

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

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

Je ne pas utiliser Benchmark.pm de Perl pour des raisons personnelles. Je l'ai vu donner des chiffres manifestement faux et, alors qu'ils étaient minimes, l'analyse comparative est inutile si vous avez des chiffres que vous ne pouvez pas faire confiance. Ces chiffres que je peux faire confiance, bien que les tests que j'ai évalués pourraient avoir besoin d'être réévalués.

+0

Hmm, intéressant. Je sais que vous ne l'aimez pas 'Benchmark', mais quand je l'utilise pour tester le code que vous avez donné ici à la place de mes tests originaux, je reçois des résultats similaires: La version non-regex est 24% plus rapide selon' Benchmark' sur ma machine. –

+0

C'est non-pcr, pas non-regex. Oops. :) –