Seite 1 von 1

Performance

Verfasst: Dienstag 30. Oktober 2007, 09:07
von stugi82
Hallo,

ich habe mit meinem Python-Code ziemliche Performance Probleme.

Deshalb habe ich mal ein Profiling durchgeführt und die Ergebnisse zeigen, dass es doch recht viele Baustellen gibt. Habe mal die wichtigsten aufgelistet (s.u.). Meine Frage ist nun, ob sich jemand damit auskennt, wie man in Python die Performance verbessern kann, und wenn ja, wie und an welcher Stelle man am meisten rausholen kann?

Code: Alles auswählen

# Aufrufe  Zeitges.  Zeit pro Aufruf ...

  1714747      9.446      0.000      9.446      0.000 :0(append)
  1595229    8.299    0.000    8.299    0.000 :0(find)
  5435392   25.278    0.000   25.278    0.000 :0(get)
  1540331    6.114    0.000    6.114    0.000 :0(group)
5584086/5583474   97.240    0.000   97.243    0.000 :0(len)
    20386   11.511    0.001   11.511    0.001 :0(open)
  1532499    9.624    0.000    9.624    0.000 :0(readline)
  6986720  142.470    0.000  142.470    0.000 :0(search)
  4624004   19.773    0.000   19.773    0.000 :0(strip)
  1604879    9.088    0.000    9.088    0.000 :0(write)
  5434477   62.779    0.000  267.356    0.000 re.py:131(search)
  5434480   52.101    0.000   78.212    0.000 re.py:219(_compile)
Leider bleibt die Formatierung hier nicht erhalten, Leerzeichen > 1 werden leider rausgelöscht...

Edit by Gerold: Code-Tags gesetzt

Verfasst: Dienstag 30. Oktober 2007, 09:30
von Rebecca
Zuerst musst du ueberpruefen, ob deine Algorithmen nicht noch optimiert werden koennen, das ist von der Programmiersprache unabhaenging. Eliminiere doppelte Berechnungen, ueberfluessige Abfragen, ueberfluessiges Umherkopieren von Daten etc., benutze moeglichst fuer alles build-in-Funktionen. Wenn man eine sehr hohe CPU-Last hast, kann man manchmal auf Lasten des Arbeitsspeichers sparen, in dem man sich Dinge merkt anstatt sie neu zu berechnen, aber das haengt natuerlich ebenfalls von den verwendeten Algorithmen ab.

Ausserdem solltest du dir die Unterschiede von Listen, Tupeln, Sets und Dictionaries klarmachen, durch die verwendung der geeigneten Datentypen kann man auch viel sparen. Also z.B. Tupel statt Listen, wenn man sie nicht mehr veraendern moechte. Dann gibts da noch einige Kleinigkeiten, z.B. sind List Comprehensions schneller als for-Schleifen. Ohne Code ist das alles schwer zu sagen, aber da du das re-Modul verwendest, compilierst du deine Suchmuster?

Wenn man sich sicher ist, dass man aus dem Algorithmus und Pythons Moeglichkeiten das Beste rausgeholt hat und das immer noch nicht reicht, kann man einzelne Programmteile mit C auf die Spruenge helfen. Die Stichworte: C Extensions, Pyrex, Ctypes

Verfasst: Dienstag 30. Oktober 2007, 09:58
von BlackVivi

Verfasst: Dienstag 30. Oktober 2007, 11:25
von BlackJack
Wenn reguläre Ausdrücke im Spiel sind, sollte man auch die mal auf Effizienz prüfen. Da kann man dank Backtracking auch ganz schnell welche basteln, die quadratische Laufzeit oder schlimmer haben.

Ansonsten möchte ich Rebecca's Aussage nochmal unterstreichen: Algorithmen und Datenstrukturen sollten zum Problem passen. Die anderen (Mikro)Optimierungen bringen immer nur einen konstanten Faktor an Gewinn.

P.S.: Rufst Du wirklich `readline()` selbst auf? Muss das sein?

Verfasst: Mittwoch 31. Oktober 2007, 08:14
von wivaxing
Vielleicht etwas offtopic, aber wie hast Du die Zeit gemessen? Sind das eigene Methoden die die Zeit der Methodenaufrufe messen oder gibt es da fertige Profiling Tools, in denen man einfach ein python Programm laufen lassen kann?

Verfasst: Mittwoch 31. Oktober 2007, 08:27
von BlackJack
Die Standardbibliothek bringt schon das Modul `profile` mit. Die Ausgabe im ersten Beitrag sieht stark danach aus.

Verfasst: Mittwoch 31. Oktober 2007, 09:19
von wivaxing
Danke. Ein simples profile.run() und so schnell interessante Informationen ist top (wenngleich die Ausgabe in eine Datei irgendeine komische Kodierung hat)! Wenn ich da an die ganzen Hürden, die ich damals mit VTune hatte zurückdenke (wenngleich noch ein etwas anderes Kaliber). danke

Verfasst: Mittwoch 31. Oktober 2007, 10:08
von BlackJack
Das Dateiformat ist das von `marshal`, aber das ist letztendlich ein Implementierungsdetail. Man sollte es sich am besten wie vorgesehen mit dem `pstats`-Browser anschauen.