_  _   ,_
/^\/^\-/ @D
~(________/ PERL.LT
|L |L
L L
Straipsniai  Funkcijos 
Funkcijos/study - optimizuoti įvedamus duomenis pakartotinėms paieškoms

  • study SCALAR
  • study

    Extra laikas panagrinėti SCALAR ($_, jei nenurodytas) laukime, kuomet darant daug "pattern matches" eilutėje prieš modifikuojantž Taip galima sutaupyti laiko, bet galima ir ne, priklausomai nuo skaičiaus prigimties ir patternų skaičiaus ir simbolių dažnio eilutėje (stringe), kurioje ieškoma - greičiausia reikėtų patikrinti ir palyginti laikus ir pažiūrėti, kuriuo atveju veikia greičiau. loop'as, kurie tikrina ir ieško daug trumpų stringų (įskaitant sudėtingesnių pattern'ų konstantines dalis, sutaupys daugiausia laiko. Galima turėti tik vieną study aktyvią - jei nagrinėti skirtingus skaliarus, pirmas jų yra nenagrinėjamas. (Kaip veikia study : padaromas sarašas su nuorodomis į kiekvieną simbolį string'e, kurioje bus ieškoma, taigi, žinoma, pavyzdžiui, kur yra visi 'k' simboliai. Iš kiekvienos paieškos eilutės, pasirenkami rečiausi simboliai, priklausomai nuo kai kurių statinių dažnių lentelių, padarytų iš C programų ir angliško teksto. Tik tos vietos, kuriose yra "rečiausi" simboliai yra tikrinamos.)

    Pavyzdžiui, štai ciklas, kuris įterpia indeksą gaminančias įvestis prieš bet kokias eilutes, kuriose randamas tam tikras patternas:

        while (<>) {
    	study;
    	print ".IX foo\n" 	if /\bfoo\b/;
    	print ".IX bar\n" 	if /\bbar\b/;
    	print ".IX blurfl\n" 	if /\bblurfl\b/;
    	# ...
    	print;
        }

    Ieškant /\bfoo\b/ , tik tos vietos $_ , kuriose yra f bus peržiūrėtos, nes f yra retesnis nei o . bendrai, tai pakankamai didelis laimėjimas, išskyrus nenormalius atvejus. Vienintelis klausimas yra ar tai sutaupo laiko labiau nei jo reikėjo sudaryti nuorodų sarašą pirmiausia.

    Pažymėtina, kad jei reikia ieškoti eilučių, apie kurias nieko nežinoma iki pat paleidimo, galima visą ciklą padaryti kaip stringą ir įvertinti (eval) jį, norint išvengti patternų perkompiliavimo kiekvienąkart. Kartu su neapibrėžiančiu $/ įvesti visus failus kaip vieną įrašą, labai paspartina darbą, dažnai atleiką jį kur kas greičiau nei specializuotos programos kaip fgrep(1). Sekantis pavyzdys peržiūri sarašą failų(@files ), ieškodamas sarašo žodžių (@words ) ir išveda tuos pavadinimus, kuriuose yra atitikmuo:

        $search = 'while (<>) { study;';
        foreach $word (@words) {
    	$search .= "++\$seen{\$ARGV} if /\\b$word\\b/;\n";
        }
        $search .= "}";
        @ARGV = @files;
        undef $/;
        eval $search;		
        $/ = "\n";		# atgal įrašomas normalus įvesties atskyrėjas
        foreach $file (sort keys(%seen)) {
    	print $file, "\n";
        }
algirdas@perl.lt 2005.04.11 - $dabar