Seite 2 von 2
Verfasst: Dienstag 11. Januar 2005, 21:34
von Dookie
Hier mal die Ergebnisse meines Benchmarks, jetzt auch mit psyco für Python2.4
Code: Alles auswählen
fritz@seneca:~/Python/Beispiele$ python2.3 fak_test.py
fak_recursive: 100000 Berechnungen brauchen 13.15 sekunden
fak_iter_while: 100000 Berechnungen brauchen 9.70 sekunden
fak_iter_for: 100000 Berechnungen brauchen 8.35 sekunden
fak_lambda: 100000 Berechnungen brauchen 8.24 sekunden
fritz@seneca:~/Python/Beispiele$ python2.3 fak_test.py psyco
fak_recursive: 100000 Berechnungen brauchen 8.23 sekunden
fak_iter_while: 100000 Berechnungen brauchen 7.78 sekunden
fak_iter_for: 100000 Berechnungen brauchen 7.39 sekunden
fak_lambda: 100000 Berechnungen brauchen 8.97 sekunden
fritz@seneca:~/Python/Beispiele$ python2.4 fak_test.py
fak_recursive: 100000 Berechnungen brauchen 8.05 sekunden
fak_iter_while: 100000 Berechnungen brauchen 5.68 sekunden
fak_iter_for: 100000 Berechnungen brauchen 4.30 sekunden
fak_lambda: 100000 Berechnungen brauchen 4.24 sekunden
fritz@seneca:~/Python/Beispiele$ python2.4 fak_test.py psyco
fak_recursive: 100000 Berechnungen brauchen 2.94 sekunden
fak_iter_while: 100000 Berechnungen brauchen 2.96 sekunden
fak_iter_for: 100000 Berechnungen brauchen 2.50 sekunden
fak_lambda: 100000 Berechnungen brauchen 3.72 sekunden
fritz@seneca:~/Python/Beispiele$
Gruß
Dookie
Verfasst: Dienstag 11. Januar 2005, 21:41
von Dookie
Hier noch der Testcode:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
Modul: fak_test
Description: Teste
Version: V0.1
Copyright: 2003 by Fritz Cizmarov fritz@sol.at
Last modified: 11. Jän. 2005
License: Free
"""
from time import time
from sys import argv, version_info
from operator import mul
if len(argv) > 1 and argv[1] == "psyco":
import psyco
psyco.full()
if version_info[:2] < (2,2):
raise SystemError("need at least Version 2.2 of Python")
def fak_recursive(n):
if n > 2:
return n * fak_recursive(n-1)
else:
return n
def fak_iter_while(n):
res = n
while n > 2:
n -= 1 # entspricht n = n - 1
res *= n # ginge auch als res = res * n
return res
def fak_iter_for(n):
res = n
for n in xrange(2,n):
res *= n
return res
fak_lambda = lambda n: reduce(mul, xrange(2,n),n)
num = 100000
msg = "%s: %d Berechnungen brauchen %.2f sekunden"
def test(funktion_name, f):
values = range(1,101)*(num/100)
t_start = time()
for val in values:
tmp = f(val)
t_end = time()
print msg % (funktion_name, num, (t_end-t_start))
test("fak_recursive", fak_recursive)
test("fak_iter_while", fak_iter_while)
test("fak_iter_for", fak_iter_for)
test("fak_lambda", fak_lambda)
Dookie
Verfasst: Dienstag 11. Januar 2005, 22:14
von Leonidas
Whoa! Das ist ja echt ein massiver Unterschied!
Verfasst: Mittwoch 12. Januar 2005, 09:02
von jens
Auf der Psyco Homepage steht eswas von mehr Speicherplatz Auslastung durch Psyco...
Hab's mal so'n bischen mit dem Benschmark von dookie getestet... Nach dem importieren von Psyco und nach jeder Schleife wird nachgeschaut wieviel Speicher der python-Interpreter verbraucht...
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
Modul: fak_test
Description: Teste
Version: V0.1
Copyright: 2003 by Fritz Cizmarov fritz@sol.at
Last modified: 11. Jän. 2005
License: Free
"""
from time import time
from sys import argv, version_info
from operator import mul
import os
def getPythonSize():
txt = os.popen('tasklist /FI "IMAGENAME eq pythonw.exe"').read()
txt = txt.split("\n")[-2]
KBstr = txt.split(" ")[-2]
KBstr = KBstr.replace(".","")
KBint = int(KBstr)
return KBint
KB1 = getPythonSize()
if len(argv) > 1 and argv[1] == "psyco":
import psyco
psyco.full()
print "import Psyco"
KB2 = getPythonSize()
print "vorher: %dKB nacher: %dKB differenz: %dKB" % ( KB1,KB2, KB2-KB1 )
if version_info[:2] < (2,2):
raise SystemError("need at least Version 2.2 of Python")
def fak_recursive(n):
if n > 2:
return n * fak_recursive(n-1)
else:
return n
def fak_iter_while(n):
res = n
while n > 2:
n -= 1 # entspricht n = n - 1
res *= n # ginge auch als res = res * n
return res
def fak_iter_for(n):
res = n
for n in xrange(2,n):
res *= n
return res
fak_lambda = lambda n: reduce(mul, xrange(2,n),n)
num = 100000
msg = "%16s: %d Berechnungen brauchen %.2f sekunden"
def test(funktion_name, f):
values = range(1,101)*(num/100)
t_start = time()
for val in values:
tmp = f(val)
t_end = time()
print msg % (funktion_name, num, (t_end-t_start))
test("fak_recursive", fak_recursive)
KB2 = getPythonSize()
print "vorher: %dKB nacher: %dKB differenz: %dKB" % ( KB1,KB2, KB2-KB1 )
test("fak_iter_while", fak_iter_while)
KB2 = getPythonSize()
print "vorher: %dKB nacher: %dKB differenz: %dKB" % ( KB1,KB2, KB2-KB1 )
test("fak_iter_for", fak_iter_for)
KB2 = getPythonSize()
print "vorher: %dKB nacher: %dKB differenz: %dKB" % ( KB1,KB2, KB2-KB1 )
test("fak_lambda", fak_lambda)
KB2 = getPythonSize()
print "vorher: %dKB nacher: %dKB differenz: %dKB" % ( KB1,KB2, KB2-KB1 )
Code: Alles auswählen
import Psyco
vorher: 3332KB nacher: 3632KB differenz: 300KB
fak_recursive: 100000 Berechnungen brauchen 1.14 sekunden
vorher: 3332KB nacher: 3672KB differenz: 340KB
fak_iter_while: 100000 Berechnungen brauchen 1.06 sekunden
vorher: 3332KB nacher: 3676KB differenz: 344KB
fak_iter_for: 100000 Berechnungen brauchen 1.00 sekunden
vorher: 3332KB nacher: 3684KB differenz: 352KB
fak_lambda: 100000 Berechnungen brauchen 1.69 sekunden
vorher: 3332KB nacher: 3692KB differenz: 360KB
Ohne Psyco:
Code: Alles auswählen
vorher: 3324KB nacher: 3328KB differenz: 4KB
fak_recursive: 100000 Berechnungen brauchen 3.45 sekunden
vorher: 3324KB nacher: 3372KB differenz: 48KB
fak_iter_while: 100000 Berechnungen brauchen 2.58 sekunden
vorher: 3324KB nacher: 3372KB differenz: 48KB
fak_iter_for: 100000 Berechnungen brauchen 1.89 sekunden
vorher: 3324KB nacher: 3372KB differenz: 48KB
fak_lambda: 100000 Berechnungen brauchen 1.72 sekunden
vorher: 3324KB nacher: 3372KB differenz: 48KB
Also 300KB gehen schon mal alleine für den import von psyco drauf... Zu sehen ist auch, das mit psyco der Speicher langsam voller wird als ohne... Ob da der Garbage Collector von psyco beeinflusst wird?
Verfasst: Mittwoch 12. Januar 2005, 12:48
von Leonidas
jens hat geschrieben:Also 300KB gehen schon mal alleine für den import von psyco drauf... Zu sehen ist auch, das mit psyco der Speicher langsam voller wird als ohne... Ob da der Garbage Collector von psyco beeinflusst wird?
Da wird einiges beeinflusst. Aber die 300kB rechtfertigen die Verbesserung auf jeden Fall, denn RAM und VM sind ja auch nicht mehr so das Problem. Den GC kannst du mit dem Modul gc sicher noch tunen.
Verfasst: Mittwoch 12. Januar 2005, 13:39
von Dookie
jens hat geschrieben:Zu sehen ist auch, das mit psyco der Speicher langsam voller wird als ohne... Ob da der Garbage Collector von psyco beeinflusst wird?
nö das hat mit dem GC nix zu tun. Psyco arbeitet quasi als "Just in time compiler". Wie das geht kann man sich schön mit
http://psyco.sourceforge.net/accu2004-psyco.tgz anschauen, Das ist ein Pythonprogramm mit Pygame, das recht anschaulich die Arbeitsweise von Psyco zeigt. Praktisch analysiert Psyco was eine Funktion macht und erstellt dafür optimierten Code, welcher natürlich für jede Funktion zusätzlich Speicher braucht. Da das zur Laufzeit geschieht, wird natürlich für jede fak-Funktion zusätzlicher Speicher angefordert, um die optimierte Version dort abzulegen. Aber erst wenn diese Funktion zur Ausführung kommt.
Gruß
Dookie
Verfasst: Mittwoch 12. Januar 2005, 13:43
von jens
Wie ist das mit größeren Programmen??? Hat jemand damit erfahrungen gesammelt?
Denn es gibt ja nur das Speicherplatz-Problem als einzigen Nachteil von Psyco, oder? Somit könnte man ihn generell einsetzten...
Verfasst: Mittwoch 12. Januar 2005, 14:29
von Leonidas
Schade, dass Psyco die optimierten Funktionen nicht auf die Platte speichern kann, so wie pyc Dateien.
Verfasst: Freitag 14. Januar 2005, 18:25
von jens
Hab mal psyco mit dem Mandelbrot von mawe
http://python.sandtner.org/viewtopic.php?t=2552 getestet:
Code: Alles auswählen
from Tkinter import *
import time
if len(argv) > 1 and argv[1] == "psyco":
import psyco
psyco.full()
print "import Psyco"
StartTime = time.time()
SIZE = 100
LEFT = -2
RIGHT = 0.5
TOP = 1.25
BOTTOM = -1.25
ITERATIONS = 20
root = Tk()
can = Canvas(width=SIZE,height=SIZE)
can.pack()
for y in range(SIZE):
for x in range(SIZE):
z = complex(0,0)
c = complex(LEFT+x*(RIGHT-LEFT)/SIZE, TOP+y*(BOTTOM-TOP)/SIZE)
norm = abs(z)**2
for count in range(ITERATIONS):
if norm <= 4.0:
z = complex(z.real*z.real - z.imag*z.imag + c.real, z.imag*z.real*2+c.imag)
norm = abs(z)**2
if norm <= 0.05:
can.create_text(x,y,fill='black',text='.')
elif norm <= 0.10:
can.create_text(x,y,fill='green',text='.')
elif norm <= 0.15:
can.create_text(x,y,fill='blue',text='.')
elif norm <= 0.20:
can.create_text(x,y,fill='red',text='.')
elif norm <= 0.25:
can.create_text(x,y,fill='yellow',text='.')
elif norm <= 0.30:
can.create_text(x,y,fill='grey',text='.')
root.update()
EndTime = time.time()
print "Dauer:",EndTime-StartTime
root.mainloop()
Hierbei brint psyco aber überhaupt keinen Vorteil ?!?!
Evtl. weil die meiste Zeit TKInter "verbraucht" ???
Verfasst: Freitag 14. Januar 2005, 19:21
von Leonidas
jens hat geschrieben:Hierbei brint psyco aber überhaupt keinen Vorteil ?!?!
Evtl. weil die meiste Zeit TKInter "verbraucht" ???
Vermutlich. Du kannst mal mit hotshot schauen, was so lange dauern würde. Aber Tk ist ja mit Tcl komisch gekoppelt, also funktioniert Tkinter vielleicht etwas unvorhersehbar.