[Cologne-pm] PERL - schnelles suchen & ersetzen in 100MB Datei
cem.sakaryali at easi.de
cem.sakaryali at easi.de
Tue Apr 27 16:51:36 CDT 2004
Wow,
ich muss noch den Code in ruhe durchgehen aber hier die Ergebnisse mit
dem Testfile:
Benchmark: timing 10 iterations of cem, kollege, wolfgang...
cem: 24 wallclock secs (23.47 usr + 0.06 sys = 23.53 CPU) @ 0.42/s (n=10)
kollege: 68 wallclock secs (58.78 usr + 9.59 sys = 68.37 CPU) @ 0.15/s (n=10)
wolfgang: 6 wallclock secs ( 6.07 usr + 0.12 sys = 6.19 CPU) @ 1.62/s (n=10)
Danke
Cem
"Wolfgang Weisselberg" <pl3rofb02 at sneakemail.com> schrieb am Tue, 27 Apr 2004 22:28:39 +0200:
> cem.sakaryali at easi.de wrote 115 lines:
>
> > ein ehemaliger Kollege hat mich gefragt, ob sein Code
> > (lese 100MB file und mache =~ s///)
> > optimiert werden koenne.
>
> Laut deinem Script moechtest du kein normales Substitute,
> ihr wollt in der ersten Zeile, in der ein Match vorkommt,
> alle Matches substituten, aber in keiner Folgezeile, richtig?
>
>
> Euer beider Code laesst 2 IMHO wichtige Optimierungen weg:
> 1. next unless $matches; # no more matches?
> 2. print($i), next unless m/$matches/; # and using qr//
>
> Begruendung:
> - Du entfernst die Substitiutions. Wenn's keine mehr
> gibt, lohnt das Testen nicht mehr, da muss man keine
> leere Schleife anfahren.
> - Matches sind ein seltenes Ereignis. Nicht-Matches sind
> haeufig. Also sollte man auf Nicht-Matches optimieren.
>
> Annahmen:
> - Zeilen-orientierte Datei (sonst sysread nehmen, und einen
> Mindest-Overlap von >= length($longest_s).)
> - Wenige Substitutes (wenige hundert) (sonst koennte bei
> genuegend Hauptspeicher ein slurpen und 'study' besser
> sein).
> - keine grosse Zahl an Matches mit substantiell gleichen
> Anfaengen (i.e. nicht Muellermeier1, Muellermeier2,
> Muellermeier3 ....), sonst sollte man gen_matchstrings
> unbedingt optimieren
> - Getestet sollte es mit echten Daten (also wirklich 100 MB,
> mit wirklich der Haeufigkeit von Matches etc.).
>
> Ach so, der Code sollte ungefaehr das richtige tun, aber ich
> uebernehme keine Garantie.
>
> Und das open will ein 'or die $!'. :-)
>
> ############################################################
>
> my %ERSETZHALTER = ( 's1' => 'e1',
> 's2' => 'e2',
> 's3' => 'e3',
> 's4' => 'e4',
> );
>
> my $file = "x";
>
> replace_and_print( $file, %ERSETZHALTER );
>
> ############################################################
>
> sub replace_and_print {
> my ( $in_file, %replaces ) = @_;
> open IN, $in_file or die "Cannot open $in_file: $!";
> my $matches = gen_matchstrings( \%replaces );
>
> while (<IN>) {
> print, next unless $matches and m/$matches/;
> print substitute( $_, \%replaces );
> $matches = gen_matchstrings( \%replaces );
> }
> }
>
> ############################################################
>
> sub gen_matchstrings { # where is map for hashes??
> my $in = shift;
> my $string = join( '|', keys %$in );
> return qr/$string/; # precompile regexp
> }
>
> ############################################################
>
> sub substitute {
> ( $_, my $replaces_href ) = @_;
> foreach my $from ( keys %$replaces_href ) {
> next unless /$from/;
> s/$from/$$replaces_href{$from}/g;
> delete $$replaces_href{$from};
> }
> return $_;
> }
>
> ############################################################
>
> Neben Perl wuerde ich auch sed o.ae. probieren.
>
> -Wolfgang
> _______________________________________________
> Cologne-pm mailing list
> Cologne-pm at mail.pm.org
> http://mail.pm.org/mailman/listinfo/cologne-pm
--
| __| / _ \ / __|(_) | C e m S a k a r y a l i
| _| | _ |\__ \| | | Eupener Str. 159, Geb. 107
|___||_| |_||___/|_| | D-50933 Koeln GERMANY
Engineering GmbH | Tel: +49 221/650 496 12 Fax: 22
http://www.easi.de | mailto:cem.sakaryali at easi.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name:
Type: application/octet-stream
Size: 0 bytes
Desc: not available
Url : http://mail.pm.org/pipermail/cologne-pm/attachments/20040427/76c75283/attachment.obj
More information about the Cologne-pm
mailing list