2011-12-05 5 views
21

estoy jugando un poco con study, una característica Perl para examinar una cadena para hacer expresiones regulares posteriores potencialmente mucho más rápida:¿Qué situaciones se benefician del estudio de Perl?

while(<>) { 
    study; 
    $count++ if /PATTERN/; 
    $count++ if /OTHER/; 
    $count++ if /PATTERN2/; 
    } 

no hay mucho decir de qué situaciones se beneficiarán de esta. Algunas cosas que usted puede hacer surgir de the docs:

  • patrones con cadenas constantes
  • Múltiples patrones
  • cadenas más cortas de destino podría ser mejor (toma menos tiempo para estudiar)

estoy Buscando casos concretos en los que no solo puedo demostrar una gran ventaja, sino también casos que puedo modificar ligeramente para perder esa ventaja. Una de las advertencias en the docs es que debe comparar casos individuales. Quiero encontrar algunos de los casos de borde donde una pequeña diferencia en una cuerda (o patrón) hace una gran diferencia en el rendimiento.

Si no ha usado study, no responda. Prefiero tener respuestas correctas bien formadas en lugar de conjeturas rápidas. No hay urgencia aquí, y esto no demora ningún trabajo.

Y, como beneficio adicional, he estado jugando con una herramienta de evaluación comparativa que compara dos carreras de NYTProf, que prefiero usar que la herramienta habitual de evaluación comparativa. Si se me ocurre una forma de automatizar eso, lo compartiré también.

+1

I * have * used 'study', si yo * debería * haber usado' study' es probablemente parte del problema al que te enfrentas. – Axeman

+0

¿Cuáles fueron los resultados de su investigación? –

+0

No tengo resultados. No me interesaba lo suficiente como para resolver el código, especialmente porque solo funciona para cadenas ASCII. –

Respuesta

7

Google volvió a esta lovely test scenario:

#!/usr/bin/perl 
# 
# Exercise 7.8 
# 
# This is a more difficult exercise. The study function in Perl may speed up searches 
# for motifs in DNA or protein. Read the Perl documentation on this function. Its use 
# is simple: given some sequence data in a variable $sequence, type: 
# 
# study $sequence; 
# 
# before doing the searches. Do you think study will speed up searches in DNA or 
# protein, based on what you've read about it in the documentation? 
# 
# For lots of extra credit! Now read the Perl documentation on the standard module 
# Benchmark. (Type perldoc Benchmark, or visit the Perl home page at http://www. 
# perl.com.) See if your guess is right by writing a program that benchmarks motif 
# searches of DNA and of protein, with and without study. 
# 
# Answer to Exercise 7.8 

use strict; 
use warnings; 

use Benchmark; 

my $dna = join ('', qw(
agatggcggcgctgaggggtcttgggggctctaggccggccacctactgg 
tttgcagcggagacgacgcatggggcctgcgcaataggagtacgctgcct 
gggaggcgtgactagaagcggaagtagttgtgggcgcctttgcaaccgcc 
tgggacgccgccgagtggtctgtgcaggttcgcgggtcgctggcgggggt 
cgtgagggagtgcgccgggagcggagatatggagggagatggttcagacc 
cagagcctccagatgccggggaggacagcaagtccgagaatggggagaat 
gcgcccatctactgcatctgccgcaaaccggacatcaactgcttcatgat 
cgggtgtgacaactgcaatgagtggttccatggggactgcatccggatca 
ctgagaagatggccaaggccatccgggagtggtactgtcgggagtgcaga 
gagaaagaccccaagctagagattcgctatcggcacaagaagtcacggga 
gcgggatggcaatgagcgggacagcagtgagccccgggatgagggtggag 
ggcgcaagaggcctgtccctgatccagacctgcagcgccgggcagggtca 
gggacaggggttggggccatgcttgctcggggctctgcttcgccccacaa 
atcctctccgcagcccttggtggccacacccagccagcatcaccagcagc 
agcagcagcagatcaaacggtcagcccgcatgtgtggtgagtgtgaggca 
tgtcggcgcactgaggactgtggtcactgtgatttctgtcgggacatgaa 
gaagttcgggggccccaacaagatccggcagaagtgccggctgcgccagt 
gccagctgcgggcccgggaatcgtacaagtacttcccttcctcgctctca 
ccagtgacgccctcagagtccctgccaaggccccgccggccactgcccac 
ccaacagcagccacagccatcacagaagttagggcgcatccgtgaagatg 
agggggcagtggcgtcatcaacagtcaaggagcctcctgaggctacagcc 
acacctgagccactctcagatgaggaccta 
)); 

my $protein = join('', qw(
MNIDDKLEGLFLKCGGIDEMQSSRTMVVMGGVSGQSTVSGELQD 
SVLQDRSMPHQEILAADEVLQESEMRQQDMISHDELMVHEETVKNDEEQMETHERLPQ 
GLQYALNVPISVKQEITFTDVSEQLMRDKKQIR 
)); 

my $count = 1000; 

print "DNA pattern matches without 'study' function:\n"; 
timethis($count, 
    ' for(my $i=1 ; $i < 10000; ++$i) { 
     $dna =~ /aggtc/; 
     $dna =~ /aatggccgt/; 
     $dna =~ /gatcgatcagctagcat/; 
     $dna =~ /gtatgaac/; 
     $dna =~ /[ac][cg][gt][ta]/; 
     $dna =~ /ccccccccc/; 
    } ' 
); 

print "\nDNA pattern matches with 'study' function:\n"; 
timethis($count, 
    ' study $dna; 
    for(my $i=1 ; $i < 10000; ++$i) { 
     $dna =~ /aggtc/; 
     $dna =~ /aatggccgt/; 
     $dna =~ /gatcgatcagctagcat/; 
     $dna =~ /gtatgaac/; 
     $dna =~ /[ac][cg][gt][ta]/; 
     $dna =~ /ccccccccc/; 
    } ' 
); 

print "\nProtein pattern matches without 'study' function:\n"; 
timethis($count, 
    ' for(my $i=1 ; $i < 10000; ++$i) { 
     $protein =~ /PH.EI/; 
     $protein =~ /KFTEQGESMRLY/; 
     $protein =~ /[YAL][NVP][ISV][KQE]/; 
     $protein =~ /DKKQIR/; 
     $protein =~ /[MD][VT][HQ][ER]/; 
     $protein =~ /NVPISVKQEITFTDVSEQL/; 
    } ' 
); 

print "\nProtein pattern matches with 'study' function:\n"; 
timethis($count, 
    ' study $protein; 
    for(my $i=1 ; $i < 10000; ++$i) { 
     $protein =~ /PH.EI/; 
     $protein =~ /KFTEQGESMRLY/; 
     $protein =~ /[YAL][NVP][ISV][KQE]/; 
     $protein =~ /DKKQIR/; 
     $protein =~ /[MD][VT][HQ][ER]/; 
     $protein =~ /NVPISVKQEITFTDVSEQL/; 
    } ' 
); 

Tenga en cuenta que la ganancia reportada es solamente alrededor de ~ 2% para el caso más rentable (proteína coincide):

# $ perl exer07.08 
# On my computer, this is the output I get: your results probably vary. 

# DNA pattern matches without 'study' function: 
# timethis 1000: 29 wallclock secs (29.25 usr + 0.00 sys = 29.25 CPU) @ 34.19/s (n=1000) 
# 
# DNA pattern matches with 'study' function: 
# timethis 1000: 30 wallclock secs (29.21 usr + 0.15 sys = 29.36 CPU) @ 34.06/s (n=1000) 
# 
# Protein pattern matches without 'study' function: 
# timethis 1000: 32 wallclock secs (29.47 usr + 0.04 sys = 29.51 CPU) @ 33.89/s (n=1000) 
# 
# Protein pattern matches with 'study' function: 
# timethis 1000: 30 wallclock secs (28.97 usr + 0.02 sys = 28.99 CPU) @ 34.49/s (n=1000) 
# 
+1

¿Qué buscaste en google?Todas mis búsquedas apestaron. –

+1

Por lo que vale, cualquier resultado con un Benchmark de aproximadamente 7% es esencialmente el mismo resultado debido a la incertidumbre en el método de prueba, por lo que este caso no es muy interesante. Me alegra que lo hayas encontrado. –

+0

@briandfoy: sí, es sobre todo mi punto: apenas parece hacer ninguna diferencia para este caso de prueba, que parece que debería ser muy apropiado. [Encontré el enlace] (http://www.cse.unt.edu/~mikler/Courses/BioCom2011/labs/perl_primer/perlbio/exercises_part1/exer07.08), olvidé agregarlo de prisa – sehe

4

voy a deje notas como respuesta, y luego lo desarrollaré en una respuesta real:

En pp.cPP(pp_study) , Tiene estas líneas curiosas (menos un comentario):

if (len == 0 || len > I32_MAX || !SvPOK(sv) || SvUTF8(sv) || SvVALID(sv)) { 
RETPUSHNO; 
} 

Parece escalares con el flag UTF8 no se estudian en absoluto.

+1

El delta 5.10.0 menciona que 'study' se configuró como no operativa para los datos UTF-8 http://search.cpan.org/~rgarcia/perl-5.10.0/pod/perl5100delta.pod – dwarring

+2

Deseo había un índice inverso para la perldelta, así que no tuve que mirar a través de todos ellos esperando que uno de ellos mencionara lo que me importaba. –

+0

@briandfoy 'git log -p -Sududio - pod/perldelta.pod' –

2

No realmente. Si busca, y la mayoría de los resultados están en el conjunto de pruebas de Perl, eso significa que nadie lo usa. Además, debido a error, solo puedes notice speed benefits on global variables. En realidad, trajo algunas mejoras de velocidad cuando se trataba de inglés (a veces incluso 2 veces más rápido), pero se tenía que hacer una variable global.

También a veces causaba infinite loops o false positives (study podría añadir insectos a su programa, incluso cuando estaba solo supone para hacerlo más rápido), y debido a que era removed (or rather, made no-op) in Perl 5.16 – nadie quería mantener una parte nadie se preocupa de todos modos .

Cuestiones relacionadas