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

Performance Rückgabe-Werte: Overhead durch Rückgabe eines Hashs



<< |< 1 2 >| >> 11 Einträge, 2 Seiten
weismat
 2006-11-10 15:55
#71630 #71630
User since
2003-08-18
142 Artikel
BenutzerIn
[default_avatar]
Ich schreibe einigen Perl-Code, der sehr performance-kritisch ist.
Um verschiedenen Implementierungen einer Parse-Funktion zu vergleichen (insb. split vs eigene Split-Implementierung zur String-Behandlung), habe ich ein Performance-Vergleichsprogramm geschrieben.
Dabei ist mir aufgefallen, daß die Rückgabe eines Hashes als Ergebnis einer Funktion einen großen Overhead hat.
(Das Parsen eines Strings in ein Hash dauert 3 mal solange wie die Rückgabe des Ergebnis-Hashes.).
Was kann man da machen? Sollte ich mit Referenzen arbeiten?
ich
 2006-11-10 16:16
#71631 #71631
User since
2003-09-19
120 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo weismat,

Quote
Was kann man da machen? Sollte ich mit Referenzen arbeiten?


wie du schon geschrieben hast.

Wenn du in einer Funktion etwas zurückgibst muss immer der komplette Speicherbereich kopiert werden.

Wenn du mit Referenzen arbeitest, wird nur die Speicheradresse uebergeben und das spart (besonders bei großen Datenkonstrukten) sehr viel Zeit.

Gruss
jan
If you tell the truth you don't have to remember anything.
-- Mark Twain
murphy
 2006-11-10 16:19
#71632 #71632
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
[quote=weismat,10.11.2006, 13:55][...] Dabei ist mir aufgefallen, daß die Rückgabe eines Hashes als Ergebnis einer Funktion einen großen Overhead hat. [...][/quote]
Wenn mich nicht alles täuscht, kann man aus einer Perlsubroutine lediglich Skalare oder Listen zurückgeben. Gibt man also einen Hash direkt zurück, so wird er in eine Liste verwandelt und muss auf der empfangenden Seite wieder neu gehasht werden -- das ist natürlich ziemlich ineffizient.

Es empfiehlt sich meiner Meinung nach auf jeden Fall, komplexe Datenstrukturen durch Referenzen zu übergeben.\n\n

<!--EDIT|murphy|1163168512-->
When C++ is your hammer, every problem looks like your thumb.
weismat
 2006-11-10 16:48
#71633 #71633
User since
2003-08-18
142 Artikel
BenutzerIn
[default_avatar]
Das mit den Referenzen hat schon mal einiges gebracht (der Overhead ist um mehr als die Hälfte geschrumpft) - trotzdem ist der Overhead durch den Funktionsaufruf immer noch hoch.
Gibt es noch so Tricks wie statische Funktionsaufrufe wie in C? Ich rufe eine Funktion 1000-1500 mal die Sekunde auf.\n\n

<!--EDIT|weismat|1163170288-->
ich
 2006-11-10 17:22
#71634 #71634
User since
2003-09-19
120 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo weismat,

mir hat mal jemand gesagt, dass er für zeitkritische funktionen CPAN:Inline::C verwendet.

Ausprobiert habe ich das noch nie, aber vielleicht hilft das was.

Gruss
jan
If you tell the truth you don't have to remember anything.
-- Mark Twain
weismat
 2006-11-10 17:59
#71635 #71635
User since
2003-08-18
142 Artikel
BenutzerIn
[default_avatar]
Ich muss gestehen, daß ich C wie die Pest hasse - vielleicht auch, weil ich eher ein funktionaler Entwickler bin.
Zurzeit bin ich dabei Perl gegen C# zu vergleichen und dann bin ich mal gespannt, wie der Vergleich ausfällt. Ich werde diesen Thread aktualisieren, wenn ich mal eine C# Version des Programms geschrieben habe. Im wesentlichen ist das ein Vergleich der Effizienz des Umgangs mit Strings - der Unterschied mit den Referenzen ist mir nur zufällig aufgefallen, weil ich die split Implementierung mit Funktionausruf gegen eine inline index Variante verglichen habe und die inline Variante Faktor 3 schneller war als die mit Funktionsaufruf und Hashrückgabe. Mit Referenz liegt der Wert immer noch bei 1.5, daher die Frage.
sid burn
 2006-11-10 18:37
#71636 #71636
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
[quote=weismat,10.Nov..2006, 15:48]Das mit den Referenzen hat schon mal einiges gebracht (der Overhead ist um mehr als die Hälfte geschrumpft) - trotzdem ist der Overhead durch den Funktionsaufruf immer noch hoch.
Gibt es noch so Tricks wie statische Funktionsaufrufe wie in C? Ich rufe eine Funktion 1000-1500 mal die Sekunde auf.[/quote]
Ich denke es ist wohl noch eher entscheidend was du genau in deinen Funktionen machst. Und manchmal kann dann auch eval() helfen.

Ich hatte mal den Fall das jemand mehrere Unterschiedliche Regexe auf paar Tausend Dateien anwenden wollte.

Er hatte alle Regexe hintereinander mit if {} elsif {} elsif {} getestet. Als er dann die Regexe in Variablen (Strings) speicherte und dann mit einer foreach Schleife arbeitete lief sein programm auf einmal ca 30 mal länger.

Problem war halt das die Regexen immer wieder mit jedem durchlauf neu compiliert wurden. Mit qr// lief es dann wieder Performant.

eval() kann in der Sitaution auch nochmal die Performance verbessern. Du baust dir sozusagen deinen Perl Code im programm als String zusammen, mit statischen Inhalten, und führst ihn dann erst aus.

Das lohnt sich aber nur wenn du z.B. Variablen hast die sich in der Funktion nicht mehr verändern, aber vom Benutzer übergeben werden. (Funktionsparameter)

Wenn du solch eine Funktion oft aufrufst (1000-1500 zähle ich schon zu oft), kann das natürlich einiges bringen, da nicht immer wieder jede Variable interpoliert werden muss. Hängt aber wohl von Fall zu Fall ab ob es Performance Vorteile bringt. Zusätzlich leidet die Lesbarkeit deutlich dadrunter.

Ansonsten kannst du wohl das meiste noch heraus holen wenn du deine Regexe Optimierst.



Da du ja von String Manipulation sprachst denke ich mal du wirst einige Regexe benutzen.\n\n

<!--EDIT|sid burn|1163176808-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
pq
 2006-11-10 21:01
#71637 #71637
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
CPAN:Devel::DProf oder CPAN:Devel::Profiler kann ganz nuetzlich sein fuer sowas.\n\n

<!--EDIT|pq|1163185355-->
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
lichtkind
 2006-11-11 02:04
#71638 #71638
User since
2004-03-22
5697 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
1000 mal die sekunde mag vielleicht etwas viel für perl sein aber vielleicht liesse sihc bei split o ä etwas sparen aber dazu müssten wir scho merh code/details sehen
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
pq
 2006-11-11 13:40
#71639 #71639
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
[quote=lichtkind,11.11.2006, 01:04]1000 mal die sekunde mag vielleicht etwas viel für perl sein aber vielleicht liesse sihc bei split o ä etwas sparen aber dazu müssten wir scho merh code/details sehen[/quote]
was ist 1000/s zu viel fuer perl? eine funktion aufrufen?
ausserdem haengt das doch von der cpu ab...
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
<< |< 1 2 >| >> 11 Einträge, 2 Seiten



View all threads created 2006-11-10 15:55.