rechenzeitunterschiede bei verschachtelten funktionen

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.
Antworten
kommando_pimperlepim
User
Beiträge: 23
Registriert: Dienstag 3. April 2007, 05:32

noch eine frage zur performance:
habe mittels time.clock (für exakte zeitmessungen unter windows, siehe http://www.python-forum.de/topic-10213. ... eitmessung) zwei routinen verglichen, die die gleiche berechnung ausführen. nur einmal über zwei verschachtelte funktionen und einmal über eine einzige funktion

Code: Alles auswählen

from time import *
from numpy import *

def f1(x):
    return x+1
def f2(x):
    return f1(x)+1
def f3(x):
    return x+1+1

a=linspace(1.0,20.0,4000000)

t1=clock()
b=f2(a)                   b=f3(a)
t2=clock()
print t2-t1
# liefert 2.42571276517   # liefert 3.17065129786
wie kann man sich erklären, dass die berechnung mit dem zusätzlichen schritt über die zwischenfunktion schneller erfolgt?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

In ``f2`` muss der Name ``f1`` erst nachgeschaut werden, danach muss die Funktion ausgeführt werden, die einen Rückgabewert bietet und dann wird in ``f2`` dieser Wert um 1 erhöht.

``f3`` hingegen nimmt den an ``x`` gebundenen Wert und erhöht ihn sofort um 2.

``f2`` macht einen Umweg über ``f1``, ``f3`` geht direkt. Das ist der Unterschied.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Ja, aber ich glaube er wollte wissen warum der "Umständlichere Weg" schneller ist ;)

lgherby
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

thelittlebug hat geschrieben:Ja, aber ich glaube er wollte wissen warum der "Umständlichere Weg" schneller ist ;)
Definiere "umständlich". Ich finde ja ``f3`` weniger umständlich. Eine andere Sache ist die Testmethode. Man sollte mit ``timeit`` und einer größeren Zahl von Iterationen testen, sonst kommt einem gegebenfalls die Streuung in die Quäre.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
thelittlebug
User
Beiträge: 188
Registriert: Donnerstag 20. Juli 2006, 20:46
Wohnort: Wien
Kontaktdaten:

Das ist ja das was ich damit meine:

f3 ist weniger umständlich aber trotzdem langsamer ;)

lgherby
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

thelittlebug hat geschrieben:f3 ist weniger umständlich aber trotzdem langsamer ;)
Ah, ok - hab falsch geschaut :oops:. Meine Erklärung ist dadurch aber nicht falsch. Den Unterschied würde ich auf die Streuung schieben. Könnte jemand das mal mit ``timeit`` testen und viele Iterationen machen? Ansonsten sind diese Werte bei einmaliger Messung nicht repräsentativ.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Also bei mir sind beide Wege 'gleich schnell' beide Funktionen schwanken zwischen 0.09 und 0.12. Ich habe Ubuntu 7.04 mit Python 2.5.1 auf einem Intel Centrino @ 1,73 Ghz. Auch bei je 100gestoppten durchläufen liegen beide Werte noch zusammen bei etwa 10.4 Sekunden.

Ich weiß nicht warum das bei dir 2.4 und 3.1 Sekunden gedauert hat.
Mein Laptop hatte 800Mhz oder 1730 Mhz eiegtlich müsste jeder schneller sein.
Gerade Windows Nutzer bei mir war Python mit Intel Compiler immer schneller als Python mit GCC.

PS: Habe den Code 1:1 kopiert.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Schon mal rein prinzipiell *kann* f3 nicht langsamer als f2 sein.

Laufen bei dir (@OP) vielleicht irgendwelche Hintergrundprozesse, die CPU brauchen? Oder Speedstepping?
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Also, hier der Benchmark-Code: #1534 (Wieso wird eigentlich usec/pass falsch angezeigt? Der Code ist quasi aus der Dokumentation von ``timeit`` übernommen)

Die Benchmark-Ergebnisse (habe ``numpy`` mal schnell selbst kompiliert, daher kann es sein, dass der da nicht die performantesten Libraries genommen hat):

Code: Alles auswählen

$ python2.5 numpymark.py
0.26 usec/pass
0.22 usec/pass
$ python2.5 numpymark.py
22.22 usec/pass
20.05 usec/pass
$ python2.5 numpymark.py
2.09 usec/pass
1.77 usec/pass
$ python2.5 numpymark.py
20.36 usec/pass
18.86 usec/pass
$ python2.5 numpymark.py
2027.87 usec/pass for composed function
2198.69 usec/pass for simple function
Ich habe am loops-Wert immer ein wenig gedreht (zuletzt war es 1000) und *meistens* ist die erste Methode langsamer. Das das beim letzten Versuch umgekehrt ist, liegt vermutlich daran, dass sich einige Hintergrundprozesse eingeschaltet haben.

Damit es fair ist, müsste man eigentlich beide Vorgehensweisen gleichzeitig ausführen lassen, also mit Threads. Benchmarken ist gar icht so einfach wie man denken könnte... Ich werde es noch mit einem anderen Computer ausprobieren, aber der ist immer noch beschäftigt ``numpy`` zu kompilieren, vielleicht kann ich den Benchmark über Nacht laufen lassen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Auf jeden Fall ist dieser Thread ein schönes Beispiel dafür, warum man immer erst am Ende optimieren sollte, und dann auch nur da, wo das Profiling einen Bottleneck zeigt; die zeigen sich nämlich oft an den seltsamsten Stellen.
Grossmeister_C
User
Beiträge: 36
Registriert: Montag 26. Februar 2007, 15:53

Soll ja auch Leute geben für die das optimieren der eigentliche Sport ist ^^
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Grossmeister_C hat geschrieben:Soll ja auch Leute geben für die das optimieren der eigentliche Sport ist ^^
Die sind aber in der Regel unter Python schlecht aufgehoben. Ich habe mal Primzahlberechnung optimiert und der Code der am schluss rausgekommen ist, war zwar definitiv schneller, aber er sah nicht mehr so schön aus. Fand ich also aus Python-Programmierer-Sicht eher unästhetisch.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten