Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]7147[/thread]

regex matching ist lahm



<< |< 1 2 3 >| >> 28 Einträge, 3 Seiten
Gast Gast
 2005-07-21 04:47
#56554 #56554
Hallo!

Ich habe einen Array und ich mache sowas damit:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
foreach $element (@list)
{
if ($element =~ /host1\.com|host2\.de|host3\.org/)
{
mach was;
}
if ($element =~ /host4\.com|host5\.de|host6\.org/)
{
mach was;
}
if ($element =~ /host7\.com|host8\.de|host9\.org/)
{
mach was;
}
if ($element =~ /host10\.com|host11\.de|host12\.org/)
{
mach was;
}
}


und das ist total lahm, wenn die liste etwas größer ist (ein paar tausend einträge). Das problem ist irgendwie, dass perl auch nicht die CPU belegt (hab hier activeperl 5.8.7). Er nimmt sich so ab und zu ein bißchen CPU zeit, so alle 10s 3%. und das dauert richtig ewig wenn er die liste bearbeitet. Kann man ihm irgendwie sagen, dass er ruhig die CPU auslasten kann für regex matching? oder das ganze sonst irgendwie beschleunigen?

Gruß
-Lev
Lev
 2005-07-21 05:06
#56555 #56555
User since
2005-07-21
8 Artikel
BenutzerIn
[default_avatar]
genauer gesagt scheint Perl vor der Schleife eine Pause einzulegen. Nach dieser langen Pause kommt aber alles ziemlich schnell. Kann aber evlt. auch daran liegen, dass die Ausgabe (aus welchen Gründen auch immer) laggt (falls das ein bekanntes Problem sein sollte: was kann man dagegen machen?)

EDIT:

Also es scheint wohl echt Ausgabelag zu sein oder sowas. Wenn ich in "mache was" auskommentiere, also nur matching mache, dann gehts flott. Kann man diesen Ausgabelag irgendwie verbessern?

-Lev\n\n

<!--EDIT|Lev|1121909285-->
Ishka
 2005-07-21 05:42
#56556 #56556
User since
2003-08-04
771 Artikel
HausmeisterIn
[Homepage] [default_avatar]
Was macht er denn inerhalb der Schleifen? Wenn er zB. irgendwelche URLs überprüft, oder mit Dateien rumhantiert, dann dauern diese Zugriffe lang, aber die RegExes gehen flott.
sub z{if(@_){1while$x[$k=rand 10];t($t=$x[$k]=1)}print map"$z[$x[$_]]$_".($_%3?
"":"\n"),1..9}sub t{$j=0;$x[$_+1]==$t&&($j+=2**$_)for 0..8;z,die"Gewinner $z[$t]
"if grep$_==($j&$_),7,56,73,84,146,273,292,448;z,die"Gleichstand\n"if@x>9&&!grep
!$_,@x}@x=4;@z=qw{. [ (};z$^T&1;while(<>){next if$_>9||$x[$_];t$t=$x[$_]=2;z 1}
Lev
 2005-07-21 11:44
#56557 #56557
User since
2005-07-21
8 Artikel
BenutzerIn
[default_avatar]
Ja ich hab Netzwerkzugriffe innerhalb der Schleifen. Also es scheint wohl kein Problem mit Geschwindigkeit, sondern mit Ausgabe zu sein. Ich mache da ab und zu print "foo" und das kommt halt viel zu spät.

Gruß
-Lev
dominicn
 2005-07-21 12:23
#56558 #56558
User since
2003-08-08
327 Artikel
BenutzerIn
[default_avatar]
Probier mal am Anfang deines Scriptes die folgende Zeile einzufügen:
Code: (dl )
$| = 1


Hilft das?
pq
 2005-07-21 15:10
#56559 #56559
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
evtl. willst du auch elsif anstatt 4 mal if benutzen, aber das weiß ich nicht.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
Strat
 2005-07-21 15:18
#56560 #56560
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
versuch mal:
Code: (dl )
1
2
3
4
5
6
if ($element eq "host1.com" or $element eq "host2.de" or $element eq "host3.org") {
...
}
elsif ($element eq 'host5.cyx' ....) {

}

wenn du nach fixen ausdruecken suchst, ist ein eq immer schneller als eine RE
und wenn du nur nach teilen suchst (also ob da ein host1.de vorkommt), dann ist index (oder hier vielleicht sogar besser rindex dein freund)
Code: (dl )
1
2
3
if (rindex($element, "host1.com") > -1 or 
   rindex($element, "host2.de")  > -1 or
   rindex($element, "host3.org") > -1) {


anstelle des ersten beispieles kannst du auch das switch-aendliche konstrukt durch einen hash ersetzen, wenn immer dieselben Parameter uebergeben werden:
Code: (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
my %switch = (
 "host1.com" => \&DoAction1,
 "host2.de"   => \&DoAction1,
 "host3.xyz"  => \&DoAction2,
 "host4.das"  => \&DoAction3);

if (exists $switch{$element} and ref($switch{$element} eq 'CODE') {
 $switch->$element->($param1, $param2, $param3, ...)
}
else {
 die "Error: no action for '$element' specified\n";
}
sub DoAction1 {
 my ($p1, $p2, $p3) = @_;
 print "Action1\n";
}
sub DoAction2 {
 my ($p1, $p2, $p3) = @_;
 print "Action2\n";
}
sub DoAction3 {
 my ($p1, $p2, $p3) = @_;
 print "Action3\n";
}

oder so aehnlich\n\n

<!--EDIT|Strat|1121944752-->
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
Lev
 2005-07-21 15:45
#56561 #56561
User since
2005-07-21
8 Artikel
BenutzerIn
[default_avatar]
[quote=dominicn,21.07.2005, 10:23]Probier mal am Anfang deines Scriptes die folgende Zeile einzufügen:
Code: (dl )
$| = 1


Hilft das?[/quote]
Danke für den Tipp, das wars. Was bewirkt es?

zu dem elseif: in jedem if steht ein "next;" drin, also elseif brauche ich da nicht.

hab jetzt die suche mit index() gemacht, obs schneller ist kann ich nicht beurteilen (die strings sind kurz und das matching an sich geht wohl sackschnell), aber übersichtlicher siehts aus als die ganzen punkte und slashes in den URLs zu escapen.

Danke für die Tipps Leute!

Gruß
-Lev
Strat
 2005-07-21 16:05
#56562 #56562
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
zu $| findest du in perldoc perlvar eine genaue erklaerung
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
Lev
 2005-07-21 16:20
#56563 #56563
User since
2005-07-21
8 Artikel
BenutzerIn
[default_avatar]
Voll krank. Diejenigen, die sich solche namen ausgedacht haben, gehören geschlagen oder sonstwas. echt unglaublich.
<< |< 1 2 3 >| >> 28 Einträge, 3 Seiten



View all threads created 2005-07-21 04:47.