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

Code durch Code erzeugen



<< >> 4 Einträge, 1 Seite
Gast Gast
 2007-04-09 20:04
#75766 #75766
Ich habe folgendes Problem.

Ich habe eine Schleife, die viele Zeile einliest und folgende Abfrage enthält:

Code: (dl )
1
2
3
4
5
6
SCHLEIFE ANFANG
if ( $fil ne "" ) {
if ( $fmode eq "-" ) { next if ( /$fil/ ); }
if ( $fmode eq "+" ) { next if ( ! /$fil/ ); }
}
SCHLEIFE ENDE


Jetzt will ich die Performance verbessern und das ganze nicht bei jedem Schleifendurchlauf abfragen.
Kann ich das Kommando irgendwie über der Schleife erzeugen und dann in den Code einfügen, sodass es ausgeführt wird?

So:
Code: (dl )
1
2
3
4
5
6
7
8
        my $com = "";
if ( $fil eq "" ) { $com = ""; }
elsif ( $fmode eq "-" && $fil ne "" ) { $com = "next if ( /$fil/ );"; }
elsif ( $fmode eq "-" && $fil ne "" ) { $com = "next if ( ! /$fil/ );"; }

SCHLEIFE ANFANG
AUSFÜHREN $com;
SCHLEIFE ENDE


Das Kommando $com müsste er dann allerdings nicht printen o.ä. sondern irgendwie an einer Stelle ausführen. Als Perl code!

Geht das irgendwie? Wißt ihr, was ich mein? Ja, oder.
Ich will diese IF-Statements aus dem Schleifendurchlauf raushalten, da sie eh immer das gleiche prüfen. $fmode und $fil sind konstante Variablen.

Dank euch!! Flo
PerlProfi
 2007-04-09 20:17
#75767 #75767
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Hast du schon mal was von eval() gehört ?
Damit kannst du zur Laufzeit code interpretieren lassen.

In deiner Schleife könnte das dann so aussehen:
Code: (dl )
1
2
eval($cmd);
die $@ if $@;

In $@ stehen die Fehler, welche bei eval() entstanden sind drin.

MfG
Linuxer
 2007-04-10 13:40
#75768 #75768
User since
2006-01-27
3890 Artikel
HausmeisterIn

user image
Hi,

naja, ob ein eval dabei hilft, die Performance zu verbessern, mag ich nicht so recht glauben.
Allerdings habe ich eval immer erfolgreich vermeiden können, daher mangelt es mir hierbei an Erfahrungswerten...

Außerdem mag ich kaum glauben, dass sich an diesen Fallunterscheidungen merklich Performance verbraucht.
Schon mal ein Profiling des Skripts gemacht und kontrolliert, womit die meiste Zeit verbraucht wird?

Devel::Profiler


edit:
Wenn Du nur auf das Vorkommen eines Strings ($fil) in einem anderen String ($_) prüfen willst, dann ist index() i.d.R. performanter:

Code: (dl )
1
2
3
4
5
#if ( /$fil/ ) 
if ( index($_,$fil,0) >= 0 )

# if ( ! /$fil/ )
if ( index($_,$fil,0) < 0 )
\n\n

<!--EDIT|Linuxer|1176198383-->
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
murphy
 2007-04-11 16:27
#75769 #75769
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
[quote=Guest,09.04.2007, 18:04][...]
Kann ich das Kommando irgendwie über der Schleife erzeugen und dann in den Code einfügen, sodass es ausgeführt wird?
[...][/quote]

Ich bin mir zwar nicht sicher, ob sich das wirklich positiv auf die Performance auswirken wird, aber warum verwendest Du keine Closure? Solange der Code, der ausgeführt werden soll, nicht wirklich dynamisch generiert ist, macht Stringevaluation meiner Meinung nach keinen Sinn.

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
my $com = sub { };

if ($fil ne '') {
  if ($fmode eq '-') {
    $com = sub { next if ( m/$fil/ ); };
  }
  elsif ($fmode eq '+') {
    $com = sub { next if ( !m/$fil/ ); };
  }
}

while ($whatever) {
  $com->();
}
\n\n

<!--EDIT|murphy|1176294606-->
When C++ is your hammer, every problem looks like your thumb.
<< >> 4 Einträge, 1 Seite



View all threads created 2007-04-09 20:04.