Beitrag von hempelr (1976 Beiträge) am Montag, 5.August.2002, 10:51.
Kleine Schleife mit extremer Laufzeit - geht es besser?
Hallo,
da ich grad eben mal die Laufzeiten meiner Scripte teste, bin ich auf ein Phänomen gestoßen, das mich etwas erschreckt.
Folgende while_get_next Schleife braucht reichlich 600 mal Länger als der Rest des Scripts, in dem auch nochmal eine while_get_next Schleife mit foreach und solchen Sachen gibt.
Wie kann man das evtl. ändern?
----------------------------------------------------
1) Schleife mit 0,55 Sekunden Laufzeit:
$lz_option = runtime();
get "sort=ort,konfes konfes~=$fkon&landkreis~=$flk", "viskart";
while(get_next(viskart))
{
$anz_optOrt="<option value=$ort>$ort</option>";
push @optOrt, $anz_optOrt if index("@optOrt", "$anz_optOrt")<0; # jeden mehrf. vorh. Ort nur einmal
}
$lz_option = runtime() - $lz_option;
----------------------------------------------------
2) Schleife mit 0,01 Sek. Laufzeit:
$lz_sort=runtime();
while(get_next("viskart"))
{
$h_bezeich{$ort}.="$bezeichnun|";
$h_name{$ort}.="$name|";
}
foreach $k (sort (keys %h_bezeich))
{
###### Ausgabe des HTML-Inhalts für jeden Ort in Variable ######
###### (Verkettung - bei jedem Schleifen-Durchlauf Inhalt erweitern) #####
@ar_bezeich=split /\|/,$h_bezeich{$k};
@ar_name=split /\|/,$h_name{$k};
$l_ort=$k;
foreach $n (@ar_bezeich)
{
$cnt_ort++;
$l=shift @ar_name;
$inf = $lcnt % 2;
if ($inf eq 0)
{
$anz_linhalt.=<<EOF;
<tr><td valign=top class=norm>
Bezeichnung: $n
<br>Name: $l
</td></tr>
${ \&tz(1,1,"$fd") }
EOF
}
$lcnt++;
$inf2 = $rcnt % 2;
if ($inf2 eq 1)
{
$anz_rinhalt.=<<EOF;
<tr><td valign=top class=norm>
Bezeichnung: $n
<br>Name: $l
</td></tr>
${ \&tz(1,1,"$fd") }
EOF
}
$rcnt++;
}
$cnt_ges=$cnt_ges+$cnt_ort;
$anz_inh_ort.=<<EOF;
<table border=0 width=90% cellspacing=0 cellpadding=0>
${ \&tz(2,2,$fd) }
<tr><td colspan=2 align=center class=gross>
<span class=dunkel><b>$l_ort</b></span>
</td></tr>
${ \&tz(2,5) }
<tr><td colspan=2 align=center class=klein id=dunkel>
Insgesamt $cnt_ort Andressen in $k gefunden
</td></tr>
${ \&tz(2,5) }
${ \&tz(2,1,$fd) }
${ \&tz(2,5) }
<tr>
<td align=center valign=top width=50% class=norm>
<table border=0 width=90% cellspacing=0 cellpadding=0>
$anz_linhalt
</table>
</td>
<td align=center valign=top width=50%>
<table border=0 width=90% cellspacing=0 cellpadding=0>
$anz_rinhalt
</table>
</td>
</tr>
${ \&tz(2,5) }
</table>
EOF
##### Variablen nach Schleifendurchlauf leeren für nächsten Durchlauf #####
#
$anz_linhalt="";
$anz_rinhalt="";
$cnt_ort=0;
$lcnt=0;
$rcnt=0;
}
$lz_sort = runtime()-$lz_sort;
----------------------------------------------------
Kann mir nur vorstellen, daß die Abfrag if index... so lange dauert, kann man das gewünschte Ergebnis auch anders erzielen?
Danke für Tip
Ruben
Antworten
Beitrag von hempelr (1976 Beiträge) am Montag, 5.August.2002, 11:23.
Was vergessen - Kleine Schleife mit extremer Laufzeit - geht es besser?
Antworten
Beitrag von Christoph Bergmann (8110 Beiträge) am Montag, 5.August.2002, 19:11.
Re: Kleine Schleife mit extremer Laufzeit - geht es besser?
Bestimmt irgendwie ;-)
Also wenn ich alles richtig verstanden habe, was Du machen willst, entdecke ich erstmal einen "logischen Haken":
Du hast im "get" ein "doppeltes" sort drin:
sort=ort,konfes
Das bedeutet: Wenn 2 oder mehr Einträge denselben Wert in "ort" haben, dann sortiere danach nach "konfes". Soweit ok, aber in der Folge sortierst Du im "get_next" alle _mehrfachen_ Einträge aus - somit ist die obige doppelte Sortierung (die ja nur bei "Mehrfacheinträgen" greift) überflüssig. Klar? Ein "sort=ort" müsste demnach eigentlich dasselbe auswerfen.
Das brint aber wohl kaum die Geschwindigkeit der Hauptteil steck im "get_next" - hier würde ich mit Hashes arbeiten:
while(get_next(viskart))
{
$anz_optOrt="<option value=$ort>$ort</option>";
$optOrt{$anz_optOrt}++;
}
Statt
müsstest Du bei der späteren Ausgabe dann sowas wie
foreach $x (keys %optOrt) ...
benutzen. Und ich würde da vielleicht auch die Sortierung reinpacken, also beim "get" weglassen:
get "konfes~=$fkon&landkreis~=$flk", "viskart";
und beim foreach dazu:
foreach $x (sort keys %optOrt) ...
Müssteste ausprobieren was schneller ist...
Antworten
Beitrag von hempelr (1976 Beiträge) am Montag, 5.August.2002, 21:56.
Re: Kleine Schleife mit extremer Laufzeit - geht es besser?
Danke erst mal für die Denkanstöße.
Also das mit der Sortierung im get leuchtet mir ein. Test wenns weg ist um Faktor 2 schneller!!
Ob das Optionfeld dynamisch mittels Hash oder Liste generiert wird, ist von der Laufzeit her brust, bringt keinen meßbaren Unterschied (hab Sortierung aus dem ersten get generell rausgenommen und sortiere entweder den Hash oder die Liste nach dem while get next, allerdings ergibt sich ja ne Sortierung wenn die Filterbedingung leer ist weil ich sie dann als * zugewiesen hab - merkt man auch gleich an der Laufzeit)
Erstaunlich sind die Ergebnisse beim zweiten get, wenn die Sortierung ganz raus kommt - das get insgesamt läuft in etwa um den Faktor 5 schneller (sortiert wird dann in der Aufbereitung der Hashs)
Und sobald im ersten get (Aufbereitung des Optionfeldes) ein Filterkriterium vorhanden ist, wird das auch um den Faktor 3-4 schneller
Interessante Ergebnisse hier:
1) sort im get (erstes nur ein Sortierkriterium:/ zweites Dreifachsortierg.):
http://dabadu.de/cgi-bin/baseportal.pl?htx=/dabadu.de/kirche/viskart_list_work&dbg=1
2) kein sort im get nur ein feld~=$filter mit hash zur dynam. Optionfeldgenerierung:
http://dabadu.de/cgi-bin/baseportal.pl?htx=/dabadu.de/kirche/viskart_list&dbg=1&a=hash
2) kein sort im get nur ein feld~=$filter mit liste zur dynam. Optionfeldgenerierung:
http://dabadu.de/cgi-bin/baseportal.pl?htx=/dabadu.de/kirche/viskart_list&dbg=1&a=liste
Antworten
Beitrag von Christoph Bergmann (8110 Beiträge) am Montag, 5.August.2002, 22:11.
Re: Kleine Schleife mit extremer Laufzeit - geht es besser?
Na, ne Geschwindigkeitsverdopplung is doch schonmal prima; und das nur wg. dem sort, das überrascht mich dann doch... Ebenfalls überrascht mich, dass der Unterschied Array / Hash so gering ist, hätte da mehr erwartet...
Allerdings bist Du mit Werten um die 0.3 doch ganz gut dabei - wie oft wird das Template denn aufgerufen?
Antworten
Beitrag von hempelr (1976 Beiträge) am Montag, 5.August.2002, 22:41.
Re: Kleine Schleife mit extremer Laufzeit - geht es besser?
jo, dachte ich auch, daß 50% effektiv sind - bin selber überrascht und auch bissel "stolz", daß wir das in Teamwork so hingekriegt haben....
Im Moment wird das Template nicht so oft aufgerufen, vielleicht so 20-30 mal am Tag, also da ist es auch nicht so dramatisch - bringt mich gleich auf die Idee, den Zugriff zu loggen.....
Danke erst mal
Ruben
Antworten
Beitrag von Christoph Bergmann (8110 Beiträge) am Montag, 5.August.2002, 23:47.
Re: Kleine Schleife mit extremer Laufzeit - geht es besser?
Hehe und mit dem Loggen verbrätst Du die gewonnene Zeit gleich wieder ;-)))
Antworten
Beitrag von hempelr (1976 Beiträge) am Dienstag, 6.August.2002, 16:56.
@CB nochmal zu Laufzeit (Hobby vom mir - hab sonst nichts besseres zu tun :-))
Antworten
Beitrag von Christoph Bergmann (8110 Beiträge) am Mittwoch, 7.August.2002, 16:20.
Re: @CB nochmal zu Laufzeit (Hobby vom mir - hab sonst nichts besseres zu tun :-))
Klar, Optimieren macht ja auch Spass ,-)
Der Fehler den man zu anfangs oft macht (zumindest gehts mir so) ist, dass man nach den Teilen sucht die an sich lange brauchen - das ist aber trügerisch, weil es geht um die Teile die am öftesten aufgerufen werden (und dann noch lange brauchen). Bei nem Template z.b. dass 1mal die Woche aufgerufen wird braucht man eigentlich garnich optimieren, weil das ruhig n paar Sekunden dauern kann - eins das jede Sekunde aufgerufen wird eben nicht... ;-)
Mit 0.1 Sekunden biste auf jeden Fall gut dabei ;)
Antworten