Thread Performance Problem mit Perl bei RegEx
(34 answers)
Opened by nomoresecrets at 2009-05-11 17:16
für eine einigermaßen brauchbare Testgrundlage:
Code: (dl
)
perl -e '$such="--TEST--"; for(0..(200*1024*1024)){ print chr(33+rand(90)); print "\n" if(rand(40)<2); print $such if(rand(1000)<5)}' > test.random.txt sollte eine TextRandomDatei erzeugen, die 200MB groß ist, und einige Suchstrings enthält. Quote mit dem Code: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #!/usr/bin/perl use strict; use warnings; my $file='test.random.txt'; # regexp vorkompilieren my $regexp=qr/--TEST--/o; # vernünftige Fehlermeldung open(TRACEFILE, '<', $file ) or die "cannot open $file $!\n"; # vor der Schleife definieren # das redefine in der Schleife bremst aus my $found=0; my $in_line; while ($in_line = <TRACEFILE>) { $found++ while($in_line =~ m/$regexp/gc); #$found++ if($in_line =~ m/$regexp/); } print "Anzahl Treffer: $found\n"; bekomme ich: mit "found++ if($in_line =~ m/$regexp/)" Quote mit "$found++ while($in_line =~ m/$regexp/gc);" Quote mit dem Code: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #!/usr/bin/perl use strict; use warnings; my $shared=100; # 100 Zeichen Überschneidung my $chuncksize=10*1024*1024; my $file='test.random.txt'; my $regexp=qr/--TEST--/o; open(TRACEFILE, '<', $file ) or die "cannot open $file $!\n"; my $found=0; my $chunk; my $old=""; while (read(TRACEFILE, $chunk, $chuncksize)) { $chunk=$old.$chunk; $found++ while($chunk =~ m/$regexp/gsc); $old = substr($chunk,-$shared,$shared); $old =~ s/$regexp//gs; } print "anzahl treffer: $found\n"; bekomme ich: Quote EDIT: Ach ja etwas zu meinem Computer: "lshw" sagt dazu: Code: (dl
)
1 *-core EDIT2: Diese Version, die "forks" benutzt, sollte auf Multiprozessormaschinen schneller laufen: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 #!/usr/bin/perl use forks; # oder "use threads", # forks bringen hier die bessere Multiprozessorunterstützung denke ich. use strict; use warnings; my $shared=100; # 100 Zeichen Überschneidung my $chuncksize=10*1024*1024; # 10 MB my $file='/home/topeg/test.random.txt'; my $regexp=qr/--TEST--/o; # maximal 4 Prozesse das macht bei 10 MB pro Prozess 40 MB... my $threads=4; open(TRACEFILE, '<', $file ) or die "cannot open $file $!\n"; my $found=0; my $chunk; my $old=""; my @running; my $pos=0; while (read(TRACEFILE, $chunk, $chuncksize)) { $chunk=$old.$chunk; # erstmal alle Prozesse erzeugen if(@running < $threads) { push(@running,get_thread($chunk)); } else { #auf einen Prozess warten ... $found+=$running[$pos]->join(); #neuen erzeugen ... $running[$pos]=get_thread($chunk); # einen weiter $pos++; # Liste wieder von vorne beginnen $pos=0 if($pos >= $threads); } $old = substr($chunk,-$shared,$shared); $old =~ s/$regexp//gs; } # auf die restlichen warten.... $pos=0; while($pos<$threads) { $found+=$running[$pos]->join(); $pos++; } print "anzahl treffer: $found\n"; exit(0); ############################################### # thread/prozess erzeugen sub get_thread { my $thread=threads->create(\&parse, shift); die "error create thread" unless(defined($thread)); return $thread; } # die Arbeit erledigen sub parse { my $found=0; my $chunk=shift; $found++ while($chunk =~ m/$regexp/gsc); $chunk=""; return $found; } Bei mir ist sie etwas langsamer (kein Wunder mit nur einem Prozessor :-) ) Quote Last edited: 2009-05-11 23:50:12 +0200 (CEST) |