Hackerboard Wiki HaboBlog
Hackerboard bei Facebook Hackerboard bei Google+ Hackerboard bei Twitter

[HaBo]

 
Code Kitchen Allgemeines Coder-Forum rund um das Programmieren eigenständiger, ausführbarer Programme.

python optimieren

Diskussion: python optimieren im Forum Code Kitchen, in der Kategorie Software Home; Anzeige Moin Ich hab hier ein script das extrem lange Laufzeit hat. Ich konnte es von 600 Jahren schon auf ...

Antwort
Alt 08.04.11, 16:52   #1 (permalink)
 
Registriert seit: 30.03.07
Biervampir Leistung: Facit NTK
Likes: 0
Standard python optimieren

Anzeige

Moin

Ich hab hier ein script das extrem lange Laufzeit hat.
Ich konnte es von 600 Jahren schon auf 9 Tage optimieren

Ein script jeder gegen jeden und auch gegen sich selbst, die Ergebnisse werden in einer Datenbank gespeichert.
Die Liste Kombination hat ~160000 Einträge, das sind alleine schon 12 Milliarden Durchläufe. Die innere while schleife produziert etwa 600 Durchläufe, kommt darauf an.
Wenn die Trefferpunkte 300 sind und der Rundenschaden 0.5.
Wie kann ich hier weiter optimieren?
Vielleicht auch mathematisch korrekt die inneren werte reduzieren, sodass weniger Durchläufe entstehen.
Ich benutze jetzt schon cython, geht da noch mehr?

http://pastebin.com/XiyL7smN


Geändert von Biervampir (08.04.11 um 19:50 Uhr) Grund: pastbin update
Biervampir ist offline   Mit Zitat antworten
Alt 08.04.11, 19:58   #2 (permalink)
CDW
Moderator
 
Benutzerbild von CDW
 
Registriert seit: 20.07.05
CDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: Opteron
Likes: 202
Standard

Zum einen kann das Laufen lassen in PyPy schon wahre Wunder bewirken:
PyPy
insbesondere bei Schleifen und simplen Rechenvorgängen.
(PyPy=Python mit JIT Compiler, hinkt allerdings der aktuellen Python Entwicklung etwas hinterher. Mit "Laufen lassen" meine ich kein Umschreiben in RPython oder ähnliches, sondern statt "python myfile.py" eben "pypy myfile.py" nutzen )

Dann:
die innere "while True" Schleife kann man sich doch komplett sparen:
Hier möchtest Du doch nur wissen, wer zuerst stirbt, richtig?
Code:
def_dies_after = Trefferpunkite_verteidiger//rundenschaden_angreifer
attacker_dies_after = Trefferpunkte_angreifer//rundenschaden_verteidiger
if def_dies_after < attacker_dies_after:
    print "Angreifer gewinnt"
elif def_dies_after == attacker_dies_after:
    print "Untentschieden"
else:
    print "Verteidiger gewinnt"
PS: nicht zu vergessen:
Code:
combinations_with_replacement
sollte ein Generator sein (also 1 Ergebnis pro Anfrage liefern und nicht etwa gleich die ganze Liste)
Edit: habe das mit dem Cython überlesen. Würde trotzdem erstmal PyPy probieren
__________________
Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf!
Selig, wer nichts zu sagen hat und trotzdem schweigt.
CDW ist offline   Mit Zitat antworten
   
HaBOT
 
- Anzeige -

Werbung ist gerade online    
Alt 09.04.11, 18:01   #3 (permalink)
 
Benutzerbild von mauralix
 
Registriert seit: 17.04.06
mauralix Leistung: 8086
Likes: 3
Standard

For-Schleifen optimiert man in Python laut meinem Pythonbuch durch die map()-Funktion oder list comprehensions.
mauralix ist offline   Mit Zitat antworten
Alt 09.04.11, 20:59   #4 (permalink)
CDW
Moderator
 
Benutzerbild von CDW
 
Registriert seit: 20.07.05
CDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: Opteron
Likes: 202
Standard

Zitat:
Zitat von mauralix Beitrag anzeigen
For-Schleifen optimiert man in Python laut meinem Pythonbuch durch die map()-Funktion oder list comprehensions.
Jein. Diese machen nicht immer einen Sinn.
Map möchte schließlich auch eine Liste/Generator/Iterator als Argument haben, um die Funktion auf das jeweilige Item anzuwenden und sowohl Map wie auch list comprehessions würden dann alle 160000 Ergebnisse auf einmal zurückzuliefern - das wäre ein merkbarer Overhead bezüglich des Speichers

Klassisches Beispiel ist range vs xrange
geTimeIt   

Code:
>>> import timeit
>>> s="""\
...   for i in range(10000000):
...     pass
...
... """
>>> s2="""for i in xrange(10000000):pass"""
>>> t=timeit.Timer(stmt=s)
>>> t2=timeit.Timer(stmt=s2)
>>> t.timeit(1)
1.1947334088550576
>>> t2.timeit(1)
0.55001822857374805

Ganz nett in diesem Zusammenhang sind übrigens die Itertools:
9.7. itertools ? Functions creating iterators for efficient looping &mdash; Python v2.7.1 documentation
__________________
Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf!
Selig, wer nichts zu sagen hat und trotzdem schweigt.
CDW ist offline   Mit Zitat antworten
Alt 10.04.11, 20:02   #5 (permalink)
Themenstarter
 
Registriert seit: 30.03.07
Biervampir Leistung: Facit NTK
Likes: 0
Standard

Vielen Dank CDW

Manchmal sieht man über die einfachste Lösung hinweg.. Die Funktion combinations_with_replacement() ist auch aus den Itertools, eine sehr nützliches Modul wie ich finde. Das Script ist jetzt jedenfalls so schnell, dass die Datenbank zum Flaschenhals geworden ist.

Ich überlege die Ergebnisse erstmal im Speicher abzulegen, in Verbindung mit Threads, aber dazu muss ich mir noch einiges anlesen.

Gruß Biervampir
Biervampir ist offline   Mit Zitat antworten
Antwort
   
- Anzeige -

Werbung ist gerade online    

[HaBo] » Software Home » Code Kitchen » python optimieren
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61