Haszprus

Mission one completed (XML parser optimalizáció)

©   Haszprus   |   fejlesztés mátrix php xml

A cégnél az első feladatom egy olyan script optimalizálása volt, amely 12-től 30 vagy akár még több MB-ig terjedő XML állományok alapján hajt végre nagyságrendileg 100-500e egymással összefüggő SQL insertet (értsd: mély és széles xml-fa).

Az eredeti progi egy 30 megás XML-lel kb. 2 perc 40 másodpercnyi munkát adott az apache.exe-nek (ennyit foglalt a prociból tehát az apache), miközben a memóriahasználat az alapjáratú 27 MB-ról felment 558 MB-ra. A program teljes futási ideje 383 másodperc volt.

Elég sok időt eltöltöttem azzal, hogy egyrészt a program logikáját megértsem, másrészt utána nézzek, hogy vajon van-e valami hatékonyabb XML parser. Miután nem találtam a használt megoldásnál jobbat (tekintve hogy az se a teljes dokumentumfát tárolta a memóriában), már majdnem ott kötöttem ki, hogy ezt bizony nem lehet (vagy én nem tudom) optimalizálni (bár persze kételkedtem), ehelyett kicsit kitesztelgettem, hogy hogyan is működik a php-ben a változók és objektumok megsemmisítése (ld. __destruct), és a megfelelő stratégiai helyen mért csapás eredményeként a program most nem növeli az apache alapjáratú memóriafoglalását egy megával sem (Érdekes módon az unset nem segített.)

Azaz az én verzióm a 30 megás XML-lel ugyanúgy 2 perc 40 másodpercig tekeri az apache.exe-t, azonban összesen csak 358 másodpercig fut (fél perc nyeremény itt, miközben sebességre még nem is optimalizáltam), és ami a lényeg, hogy 27-ről nem 558 MB-ra nyomja fel az apache memóriahasználatát, hanem mindössze 29-re. Nem kell mondani, hogy ez mennyire előnyös egy olyan környezetben, ahol más dolgok is futnak (ti. ez egy webszerver).

Amikor nekiálltam a dolognak, egy nagyságrendi változást akartam volna elérni, aztán ahogy beleástam magam, megelégedtem volna akár egy memóriafelezéssel is, végül már majdnem teljesen feladtam, de arra álmomban sem gondoltam, hogy sikerül a memóriahasználatot úgy ahogy van megszűntetni Ettől igen jó kedvem lett

Rulz.

RSS: hozzászólások ehhez a bejegyzéshez 8 hozzászólás

Szólj hozzá Te is!

Hmm… Mivel debugolsz egyébként? Használsz valami spec progit vagy simán a hagyományos apache logot figyeled?

Tehát, ha jól értem az SQL parancsokat változtattad meg vagy alakítottad át.
Igy van?

ScoobyZoli, én inkább azt tippelem, hogy a megfelelő helyeken való rásegítéssel rávette a PHP-t, hogy ugyan takarítsa már el a memóriából azokat az ojjektumokat, amiket úgyse használ. (Stratégiai helyeken való unset-telés, gondolom).

Érdekes módon az unset nem segített.
Tamás, Ha jól értelmezem Haszprus szövegét, akkor nem az unset-ek segítettek…

Hedge, így van, az unseteknek semmi hatása nem volt, ehelyett az objektumok belsejében tudtam a változókat nullra állítani egy új tagfüggvénnyel. Persze ehhez egy tökismeretlen kódban előbb rá kellett jönni hogy az objektumok nem is pusztulnak el (még unset ellenére sem) stb.

ScoobyZoli, SQL-hez az eddigieknek nem volt köze, de a következő két napban ott is optimalizálni fogok, és az talán sebességnövekedést is magával hoz. (Valamennyit biztosan, kérdés, hogy mennyit.)

Hedge, nem használok semmit, apache logot se figyelek, a php futási ideje ugye time(), az apache memóriahasználata meg task manager. De ha tud valaki valami debuggert, az királyos lenne.

Hedge, fuck, reggel volt még akkor

Haszprus, Ilyet asszem akkor szokott, ha két vagy több ojjektum körkörösen egymásra hivatkozik: a garbage collector nem tudja eltakarítani őket, mert azt látja, hogy mindegyikre van még hivatkozás, és nem veszi észre, hogy ezek egy külön komponenst alkotnak a hivatkozási gráfban. A megoldás ezek szerint pont az, amit csináltál, legalábbi feltételezem, hogy a null-ra állítgatásokkal ezt a hivatkozási kört szakítottad meg valahol.
(Azért tippelek erre, mert alapban a PHP unset-re automatikusan visszaadja az objektum által foglalt memóriát az OS-nek, ha nincs rá hivatkozás máshonnan)

Memóriahasználat lekérdezésére mellesleg nem kell az Apache-ot nézegetni, van PHP-ben egy memory_get_usage nevű függvény (és esetleg a memory_get_peak_usage is érdekes lehet).
Debugger: Xdebug extension?

Xdebug FTW szerintem is

Mellesleg grat, azért ez egy elég nagy eredmény..

Hozzászólásod:


Nem vagy bejelentkezve, de...

A)
hozzászólhatsz regisztrálatlanul...

B)
ha regisztrálva vagy, bejelentkezhetsz...