Python programok gyorsabb futtatása

Sziasztok!

Csináltam egy adatfeldolgozó szoftvert, amely lelkét néhány napos munkával Python-ban implementáltam.
Sokszáz MB-os adathalmazt dolgoz fel, értékel ki. Asszociatív tömbök tömkelegével játszik.

Kíváncsiságból a pypy-vel is futtattam, illetve újabb néhány nap alatt megírtam C-ben is.

Futási eredmények:
/usr/bin/python feldolgozo.py # 3,5 perc
cython és gcc-vel lefordítva # kb. 2 perc
/usr/bin/pypy feldolgozo.py # 40 másodperc
C-ben megírva ugyanez a feldolgozó: 7 másodperc

Kérdésem: lehet-e tovább gyorsítani a python-t valahogy?
Esetleg a kódolás terén mire érdemes odafigyelni, ami erőforráspazarló Python esetén?

Hozzászólások

Ez engem is erdekelne, mert nagyon szeretem a nyelvet, de nagyon lassu es sok memoriat eszik. En is eloszor ebben irtam meg egy teszt rendszert, amivel egy flottakoveto rendszer teherbirasat teszteltem volna. Hat kidoglott a program es keptelen volt egy (akkor) modern quad core gep leterhelni egy P3-at, amin meg adatbazist is kellett irni. Atirtam a teszt rendszert C-be es 3 szervert egyszerre (P2,P3,P4) is kepes volt maximalisra kihajtani mikozben a negy magos gepnek meg boven maradt eroforrasa.

Sub.

Ez a 3.5 perc vs. 7s az piszok nagy különbség.

... python esetén az asszociatív tömbök kényelmesek, de igen lassúak. A bitműveletek (bittologatás, egyesével mazsolázás) sem egy gyors mutatvány. Mindkettőből sok kellett az adatdekóderemhez, de egyéb okokból jó lenne, ha Pythonban maradna. Szóval ezért ilyen kiugróan lassú.

A Python előnye és hátránya, hogy egy

python<enter>


a = 5
help(a)

hatására ha kipróbálod, nem egy "int a=5;" történik, hanem egy int típusú osztály jön létre, saját metódusokkal. Ez kényelmessé teszi, ám JIT nélkül őrülten lassúvá és JIT-tel sem mondható közel C sebességűnek.

A C "struct" kulcsszava ehhez képest fapad, ám igen gyors (direkt memóriás, nem valami képlékenyen formálható osztály) és sok jó trükk megcsinálható vele. Ahogy a bit tologatások is közvetlen CPU utasításra fordulnak. Ellenben kevésbé kényelmes (és gyorsan tákolható), mint a Python list, dict, set, ... osztályainak kezelése.

Egyébként ha például stringeket kell feldolgozni, akkor elmondható, hogy

- C-ben írva 10 másodperc
- Pypy esetén kb. 30 másodperc
- Python esetén 100 másodperc

körüli string feldolgozási idővel lehet számolni.
Egy érdekes teszt eredménysor cPython és Pypy között: http://speed.pypy.org/

Szia!
Előre mondom, hogy nem vagoyk expert a témában, de mostanában nekem is voltak ilyen problémáim.
A különböző python/pypy-t néztem én is, de ezen felül az merült még fel bennem, hogy nálad nem lehet esetleg párhuzamosítani? Mert ha a programodban lenne erre lehetőség, akkor pl. az én esetemben ugyanaz a függvény több objektumra futtatva szétosztható szálakra, és így akár több gép is tud rajta dolgozni.
(Multiprocessing (csak egy gép), IPython Cluster (az IPython notebook nekem a mostani problémához nagyon kézreáll, és az állam leesett milyen jó), SCOOP-pal nézegettem.)

Előre bocsájtom, hogy messze nem vagyok programozó, csak tippelek!

Van php -hoz egy xdebug nevezető modul, ez többek között futásidő elemzésre is használható, valami hasonló nincs pythonhoz?

[update]
De van ( és persze a profileing cimszó alatt keresendő :-P ) szóval erre gondoltam: http://stackoverflow.com/questions/1896032/using-cprofile-results-with-…

----
올드보이
http://molnaristvan.eu/

Subs.

Azért C sebessėget én nem várnék egy interpreteres OO nyelvtől.

Igen, de ezt most mire?
A jit sem lesz soha C sebességű.
De szerintem még C++ sem, ami tudtommal lassúbb a hagyományos C-nél.

Én most azon vagyok kiakadva, hogy ha belerakok egyetlen re.findall()-t a feldolgozó részbe, akkor a 0.3sec futásidő felkúszik 2sec-re. És még semmit sem csinál, csak végigolvas egy logfile-t és egy regex alapján kiszed a sorokból pár mezőt.

Külön szám, hogy... khm... szóval nem igazán nyerő. :)

Ugyanaz a unittest, ha az alap python futtatja, akkor 1.01-1.07sec a futásideje.
Ha pypy futtatja, akkor 1.31-1.35.
Humoros.
Ha meg kiveszem belőle a problémás self.regex.findall(string) sort, akkor 0.3sec körüli időket kapok. :))

Kevés különbség van a c structok és a cpp osztályok között. Azt a keveset is mellőzni lehet adott esetben, ha egy mérés azt igazolja, hogy egy konkrét kódrészlet a szűk keresztmetszet. Az a jó a cpp -ben hogy nincs benne mágia, mindig lehet tudni hogy kb. milyen c kódnak felelne meg amit írtál, magyarán még mindig nagyon alacsony szintű nyelv. Csak jóval kevesebbet kell gépelni.

Az objektumoknak van valamennyi overheadje. Nem sok.
Amikor én C++-ban programoztam, akkoriban az inline függvények meg lényegesen gyorsabbak voltak, és a C nem tudott ilyesmit. Szóval a kódtól függően picit lassabbtól valamivel gyorsabb között volt valahol. De nem volt szörnyű nagy különbség egyik irányban sem.

Lehet, hogy mostanában a C fordítók is optimalizálnak és maguktól inline módon tesznek be függvényhívásokat, nem tudom, nem követem a változásokat.

Nem tudnád vagy akarnád úgy kombinálni, hogy C kiterjesztésként hívod meg az időigényes részt? Abból is csak az egyszerűbben kódolhatót, hogy tartanád azt hogy a munka oroszlánrészét vegye le a válladról a Python, de az egyszerű de sokszor hívott kódot meg megírod C-ben?

Common Lispből akár 10 másodperces futási időt is ki lehet hozni.

Térj át Go-ra (golang.org)!

Van "duck typing" jellegű interface, de statikusan típusos, fordításnál sok-sok hiba kijön, ami a python-nál csak futás közben (vagy sem, mert mondjuk nem megy a hibát tartalmazó ágra).

Python profilernek nézz utána.

Kapsz egy szép listát, hogy hol tölti az időt. Észreveszed majd, hogy hol érdemes megnézni.

Egyszer kellett használnom, az én esetemben leginkább a memória foglalás volt sok, és ez evett sokat.
El tudtam hagyni olyan dolgokat, mint pl. a konstruktorban pár dolog beállítását és volt egy lépés, amiben az objektumok le lettek másolva.
Ettől a pár dologtól hatalmasat gyorsult.

De persze nem lett olyan gyors, mint ugyanaz C++-ban megírva.

De a python nem arra van, hogy gyorsan futó programot készítsek, hanem arra, hogy sokkal rövidebb idő alatt, elkészüljön valami, amit utána egyszerű karbantartani.