Python beschleunigen. Was hilft?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
burli
User
Beiträge: 1116
Registriert: Dienstag 9. März 2004, 18:22

Freitag 13. März 2009, 09:05

Moin, mich würde mal interessieren, welche Maßnahmen Python Beine machen, ohne das man inkompatibel zum Standard wird.

Die einfachste Maßnahme: 64 Bit. Bringt das was oder bewegt sich das bestenfalls im messbaren Bereich?

Die nächste Möglichkeit, die ich gefunden habe, ist psyco. Das Projekt wird nicht mehr weiterentwickelt, scheint sich aber in einem stabilen und brauchbaren Zustand zu befinden. Wirklich spürbare Änderungen konnte ich jedoch noch nicht feststellen (oder ich mache was falsch? Es reicht doch, in das Startscript psyco zu importieren und aufzurufen, oder?)

Dann hab ich noch PyPy gefunden. Aber daraus werde ich noch nicht wirklich schlau wie man den einsetzen kann.

Gibt es sonst irgend welche Möglichkeiten (außer sauber zu programmieren ;))?
Benutzeravatar
kbr
User
Beiträge: 872
Registriert: Mittwoch 15. Oktober 2008, 09:27

Freitag 13. März 2009, 09:35

burli hat geschrieben:Moin, mich würde mal interessieren, welche Maßnahmen Python Beine machen, ohne das man inkompatibel zum Standard wird.

Die einfachste Maßnahme: 64 Bit. Bringt das was oder bewegt sich das bestenfalls im messbaren Bereich?
64 Bit erweitern den möglichen Adressraum. Damit kann sogar ein Geschwindigkeitsnachteil verbunden sein.
Allgemein gilt: nutze Funktionen der Standardlibrary; die Chancen stehen gut, dass zeitkritische Abläufe in C programmiert sind. Sind sie das nicht, schreibe selbst eine C-Erweiterung. Die beste Empfehlung aber ist ein effizienter Algorithmus.
burli
User
Beiträge: 1116
Registriert: Dienstag 9. März 2004, 18:22

Freitag 13. März 2009, 09:43

Ich habe gerade mal psyco auf zwei Mandelbrot Progrämmchen losgelassen. In beiden Fällen hat es eher gebremst. Mache ich da was falsch oder funktioniert das einfach nicht?

Hier mal das einfache Beispiel

Code: Alles auswählen

#!/usr/bin/python
import psyco
#psyco.log()
psyco.full()

from py_kohn_bmp import kohn_bmp

print "\nPyMandel - Mandelbrots generated in Python\n"
print "Copyright 2007 - Michael Kohn"
print "mike@mikekohn.net - http://www.mikekohn.net/\n"

# Changing the values below will change the resulting image

image_width=640
image_height=480

start_real=-2.00
start_imag=-1.00
end_real=1.00
end_imag=1.00

my_bmp=kohn_bmp("out.bmp",image_width,image_height,3)

colors = [ [0,0,0], [255,0,0], [127,0,0], 
           [127,127,0], [0,127,0], [0,255,0],
           [0,255,0], [0,255,127], [0,127,127],
           [0,127,255], [0,0,255], [127,0,255],
           [127,0,255], [255,0,255], [255,0,127],
           [127,127,0], [255,0,0] ]


inc_real=(end_real-start_real)/image_width
inc_imag=(end_imag-start_imag)/image_height

start=complex(start_real,start_imag)
end=complex(end_real,end_imag)

print str(start)+"  "+str(end)

for y in range(image_height):
  print str(y)+"/"+str(image_height)

  for x in range(image_width):
    c=complex(start_real+(inc_real*x),start_imag+(inc_imag*y))
    z=complex(0,0)
    count=169

    while count>0:
      z=(z**2)+c
      if abs(z)>2: break
      count=count-1

    c=int(count/10)
    my_bmp.write_pixel(colors[c][0],colors[c][1],colors[c][2])

my_bmp.close()


rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Freitag 13. März 2009, 10:03

Hi

Mach mal Funktionen daraus ... ich glaube psyco optimiert Funktionen und kein Modul Code (was sowieso nicht so gut ist).

Ansonsten waere da noch Cython, mit dem kannst du einfach C-Erweiterungen schreiben (python mit erweitertem Syntax, welcher dann in C-Code umgewandelt wird).

Gruss
burli
User
Beiträge: 1116
Registriert: Dienstag 9. März 2004, 18:22

Freitag 13. März 2009, 10:27

Das mit den Funktionen habe ich auch vermutet. Deshalb habe ich noch ein zweites Mandelbrot Programm ausprobiert, das eine Klasse hat. Ich hab sogar extra ein Startscript geschrieben, das das andere Modul importiert und die Klasse aufruft. Aber...

Beim ersten Programm, das ich hier gepostet hab, lag es an der fehlenden Funktion, beim zweiten Programm lag es daran, das die eigentliche Rechenpower wohl aus Numpy stammt (weshalb es auch deutlich schneller war). In dem Fall hat wohl die Zeit, die psyco zum compilieren gebraucht hat, den Geschwindigkeitsvorteil aufgefressen.

Und jetzt kommt der eigentliche Witz: das oben abgedruckte Programm ohne Funktion braucht 1m13s ohne psyco. Mit psyco brauchte es 1m19s

Das gleiche Programm in einer Funktion verpackt braucht ohne psyco nur 1m0s und mit psyco 0m22s

Dh allein dadurch, das man den Programmcode in eine Funktion gepackt hat, macht das ganze schon deutlich schneller. Das Programm habe ich im übrigen von hier
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Freitag 13. März 2009, 11:42

burli hat geschrieben:Und jetzt kommt der eigentliche Witz: das oben abgedruckte Programm ohne Funktion braucht 1m13s ohne psyco. Mit psyco brauchte es 1m19s

Das gleiche Programm in einer Funktion verpackt braucht ohne psyco nur 1m0s und mit psyco 0m22s
Das ist leicht erklärbar: psycho selber braucht auch etwas Zeit und lohnt sich erst so richtig, wenn etwas vielfach aufgerufen wird. Bei einer Abfolge von Statements, die nur einmal aufgerufen werden, könnte psyco soviel optimieren wie nur möglich: Da kein weiterer Aufruf erfolgen wird, wirkt es sich nicht aus. Deshalb die Beschränkung auf Funktionen. Allerdings wirkt sich psyco da schon bei zweiten Durchlauf einer Schleife aus.

Bei mir hat psyco bei einer 32bit Architektur einen guten Schub gebracht. Allerdings nicht gut genug, so daß ich auf C/C++ ausgewichen bin. Ich hatte auch mit Pyrex rumexperimentiert - nicht mehr mit Cython, was ja gewissermaßen der Nachfolger ist. Mit Pyrex war der entsprechende Code schon wieder ein Stückchen schneller - aber mir immer noch nicht schnell genug. Erst mit reinem C war es mir schnell genug. Der Grund dafür wird schnell klar, wenn man in C-Files guckt, die durch Pyrex (Cython) generiert werden: Sehr viele Python-API-Aufrufe.

Ich schreibe das Alles, weil Du mit dem Mandelbrotskript etwas zeigst, das ein bißchen nach Numbercrunching aussieht. Und genau das wollte ich auch. Also: Das Einzige was hilft ist messen, hochrechnen und ausprobieren. (Nur nebenbei: Pures hätte bei mir, bei dem Fall an den ich hier dachte, 16 Jahre gebraucht und in C war ich bei ca. 1-2 Wochen Rechenzeit - der Aufwand hatte sich also wirklich gelohnt.)

Gruß,
Christian
burli
User
Beiträge: 1116
Registriert: Dienstag 9. März 2004, 18:22

Freitag 13. März 2009, 12:46

CM hat geschrieben:
burli hat geschrieben:Und jetzt kommt der eigentliche Witz: das oben abgedruckte Programm ohne Funktion braucht 1m13s ohne psyco. Mit psyco brauchte es 1m19s

Das gleiche Programm in einer Funktion verpackt braucht ohne psyco nur 1m0s und mit psyco 0m22s
Das ist leicht erklärbar: psycho selber braucht auch etwas Zeit und lohnt sich erst so richtig, wenn etwas vielfach aufgerufen wird.
Nein, der Witz war, das das Programm ohne psyco schon schneller lief, nur weil ich den wesentlichen Teil in eine Funktion gepackt habe. Das hatte nichts mit psyco zu tun.

Ich habe gerade auch mal etwas weiter experimentiert. Ich habe psyco mal auf den Mediaplayer "Listen" losgelassen, der komplett in Python geschrieben ist. Ergebnis: Das einlesen der Musikbibliothek ohne psyco dauerte 22 Sekunden, mit psyco nur noch 12.

Das Python vermutlich nie in die Nähe von C rankommen wird dürfte klar sein. Aber bei vielen Anwendungen ist das auch nicht nötig. Dafür ist die Entwicklungszeit in Python erheblich kürzer und die Pflege vom Code ist einfacher.

Vielleicht ist psyco (oder PyPy) ja ein gutes Mittel, um zumindest existierenden Programmen einen Kick zu geben.

Ich weiß das psyco nicht mehr weiterentwickelt wird sondern der Entwickler beteiligt sich anscheinend jetzt an PyPy. Nur bin ich da noch nicht durchgestiegen. Kann ich mit PyPy das gleiche machen, was ich hier mit psyco gemacht habe? Und wenn ja, wie?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Freitag 13. März 2009, 17:24

Noch ein paar Worte zu psyco:

Dass psyco nur auf Funktionen wirkt, wurde ja mittlerweile klar genug gesagt.

Ob psyco zur Beschleunigung beiträgt, hängt sehr davon ab, wie man den Code schreibt. Manchmal muss man den Code sogar etwas unpythonischer machen, damit psyco mehr bringt. Es gibt aber auch Fälle, da bringt psyco nichts, weil der Code die Python builtins oder andere Spezialitäten (wie z.B. Slicing) nutzt.
Bei Zeichenkettenoperationen und bei langen Integerzahlen kann man mit psyco ebenfalls nicht viel holen.

Ein konkretes Beispiel der letzten Zeit: Beim SPOJ-Problem PRIME1 hatte ich eine ziemlich fixe Version mit 0.40s Laufzeit (für kurze Zeit ungeschlagen ...); dann habe ich an ein oder zwei Schlüsselstellen im Code etwas verändert mit dem Ergebnis, dass der ansonsten gleiche Code jetzt ohne psyco in 0.31 s läuft - mit psyco wird der praktisch nicht schneller. Mittlerweile hat jerch einen Algorithmus geschrieben, der psyco nutzt und die gleiche Aufgabe damit in 0.25 s löst.
burli
User
Beiträge: 1116
Registriert: Dienstag 9. März 2004, 18:22

Freitag 13. März 2009, 17:46

Mir ist klar, das psyco keine Universallösung ist und im Extremfall sogar eher bremst als beschleunigt. Das dürfte aber nur sehr selten der Falls sein, außerdem kann man es ja einfach austesten ob es funktioniert und ob es was bringt. Man muss nur ein paar Zeilen in das Startscript einfügen, was eigentlich jeder tun kann.

Es ist auch klar, das psyco nur Python Module compilieren kann. Module, die eh schon in C implementiert sind, hilft es nichts.

Der Vorteil von psyco ist ja, das es ohne spezielle Änderungen am Programm und mit CPython funktioniert. Man sollte also durchaus öfter davon Gebrauch machen.

Wie ich am Beispiel von Listen gesehen habe bringt es durchaus einiges.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 13. März 2009, 18:51

Zudem Psyco afair nur auf 32-Bit-Platformen funktioniert.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
burli
User
Beiträge: 1116
Registriert: Dienstag 9. März 2004, 18:22

Freitag 13. März 2009, 19:02

Leonidas hat geschrieben:Zudem Psyco afair nur auf 32-Bit-Platformen funktioniert.
Wobei ich von 64 Bit eh noch nicht ganz überzeugt bin. Bisher hatte ich dadurch eigentlich noch keine Vorteile, aber den einen oder anderen Nachteil. Hab bei mir erstmal überall wieder 64 Bit installationen entfernt und durch 32 Bit ersetzt. Vielleicht in einem Jahr nochmal schauen
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 13. März 2009, 19:07

burli hat geschrieben:Wobei ich von 64 Bit eh noch nicht ganz überzeugt bin. Bisher hatte ich dadurch eigentlich noch keine Vorteile, aber den einen oder anderen Nachteil.
Wenn man zum Beispiel mit Festplattenverschlüsselung arbeitet ist es praktisch und die Möglichkeit einen Adressraum von 2**64 ist psychologisch nicht schlecht. So weiß ich dass ich beliebig viel RAM reinstecken kann ohne dass es zu Problemen führt. Zudem sind 64-Bit Systeme eben wegen dem RAM unproblematischer wenn es um Hostsysteme geht die mehrere Xen-Instanzen verwalten. Da freut man sich über jede 2 GB die man reinstecken kann. Lieber das als das herumgeeiere mit PAE. Zudem Binärdistributionen in der Regel besser optimierte Pakete für amd64 bieten, da man dort nicht auf alte Systeme wie Pentium etc. Rücksicht nehmen muss sondern viele Techniken wie SSE ohne wenn und aber verwenden kann.

Nachteile habe ich hier mit 64-Bit eigentlich auch keine. Psyco brauche ich nicht und andere JITs laufen durchaus auf amd64.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
burli
User
Beiträge: 1116
Registriert: Dienstag 9. März 2004, 18:22

Freitag 13. März 2009, 19:31

Leonidas hat geschrieben:
burli hat geschrieben:Wobei ich von 64 Bit eh noch nicht ganz überzeugt bin. Bisher hatte ich dadurch eigentlich noch keine Vorteile, aber den einen oder anderen Nachteil.
Wenn man zum Beispiel mit Festplattenverschlüsselung arbeitet ist es praktisch und die Möglichkeit einen Adressraum von 2**64 ist psychologisch nicht schlecht. So weiß ich dass ich beliebig viel RAM reinstecken kann ohne dass es zu Problemen führt. Zudem sind 64-Bit Systeme eben wegen dem RAM unproblematischer wenn es um Hostsysteme geht die mehrere Xen-Instanzen verwalten. Da freut man sich über jede 2 GB die man reinstecken kann. Lieber das als das herumgeeiere mit PAE. Zudem Binärdistributionen in der Regel besser optimierte Pakete für amd64 bieten, da man dort nicht auf alte Systeme wie Pentium etc. Rücksicht nehmen muss sondern viele Techniken wie SSE ohne wenn und aber verwenden kann.

Nachteile habe ich hier mit 64-Bit eigentlich auch keine. Psyco brauche ich nicht und andere JITs laufen durchaus auf amd64.
Naja, ich hab weder Rechner mit mehr als 2GB noch verschlüssele ich meine Partitionen oder arbeite mit virtuellen Systemen.

Welche JITs gibts denn noch so? Im Moment kenne ich nur PyPy und damit komme ich noch nicht klar. Gibts da ein einfaches HowTo?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 13. März 2009, 19:44

burli hat geschrieben:Welche JITs gibts denn noch so?
HotSpot oder GNU lighning, noch etliche mehr.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Freitag 13. März 2009, 19:57

burli hat geschrieben:Welche JITs gibts denn noch so? Im Moment kenne ich nur PyPy und damit komme ich noch nicht klar. Gibts da ein einfaches HowTo?
Pypy ist nicht als CPython-Ersatz für Endbenutzer gedacht. Wenn dir die Doku nicht reicht, bist du nicht die Zielgruppe. Das ist alles noch hochexperimentell und ein funktionierenden JIT für Python kriegst du damit auch (noch) nicht.
Antworten