Kód-optimalizálás php-ban
Fogyókúra – memóriaoptimalizálás
A memóriaoptimalizálási lépésben a támadott kód a teljes script. Bármelyik sarokban lehet olyan rész, ami működőképes marad egy kicsivel kevesebb memóriahasználattal is.
Most átmegyünk behajtóba, és az eddig kölcsönadott memóriából kérünk vissza. Nem is keveset…
Támadási pontok:
- nem használt adatok mellékessé tétele
- kézi vezérlésű “szemétgyűjtés” (garbage collect)
- adatstruktúra újratervezése
Nem használt adatok
A negyedik variációnál elkezdtük a cache-tömb kulcsait vizsgálni, és ezáltal a tömb érték oldalán lévő adatok már csak a foreach
-ben kerülnek elő:
[...] foreach ($variation_cache[$passengers - $rn] as $variation) { [...] |
Van egy kiterjesztett változata a foreach
-nek, amivel a kulcsot is ki tudjuk olvasni lokális változóba. Ezzel a megközelítéssel a tömb érték oldala teljes egészében feleslegessé válik, mivel mindenhol csak a kulcsokon végzünk műveletet. Azt pedig hamar beláthatjuk, hogy az aktuális variáció mint érték letárolásához képest a boolean:true sokkal kevesebb helyet foglal.
Módosítás után:
[...] foreach ($variation_cache[$passengers - $rn] as $variation => $devnull) { [...] $variation_cache[$passengers][$actual_variation] = true; [...] $variation_cache[$passengers][$rn] = true; [...] |
Manuális GC
A kód csak olyan régebbi variációkat használ, amik nem kisebb, mint 4 távolságra vannak az aktuális vendégszámtól:
Q(n) = unique( Q(n-1) + Q(n-2) + Q(n-3) + Q(n-4) )
Éppen ezért minden ennél régebbi variáció-tömb eldobható, mert a későbbiekben nem lesz rá szükség.
function calc_room_use ($passengers, &$variation_cache) { [...] unset($variation_cache[$passengers - 4]); } |
Ezzel a kis aprósággal rávesszük a szemétgyűjtőt, hogy szabadítsa fel a már nem használt memóriaterületet. Az automatikus gyűjtés ugyanis nem működne rá, mivel folyamatosan életben marad a $variation_cache, és ezáltal a nem használt tömbökre mutató címek is.
Adatstruktúra újratervezése
Sok esetben kódmódosítások alkalmával előfordul, hogy korábbi verzióból megörökölt adatstruktúrákkal, elgondolásokkal dolgozunk tovább, holott lenne gyorsabb/kisebb megoldás is. Ilyenkor érdemes meglépni a változtatást, mert adott esetben sokat nyerhetünk vele.
Az aktuális variációt tartalmazó szövegsor, az emberi fogyasztásra alkalmas kialakítás miatt tartalmazott “,”-t az első verzió óta. Ez nagyban megkönnyítette az explode és implode olvashatóságát is (funkcionalitását nem befolyásolta, hogy van-e elválasztó vagy nincs).
Ez jelenleg a következő (30 főre):
$actual_variation = "1,1,1,1,2,2,3,3,4,4,4,4"; |
Mivel azonban tudjuk, hogy a szobaméreteket adó számok kivétel nélkül egyjegyűek, így nincs szükség elválasztó karakterre, hogy az algoritmus hiba nélkül tudjon futni. Egy apró módosítással a variáció már csak majdnem fele mennyiséget foglal, számítási szemszögből azonban teljesen egyenértékű:
$actual_variation = "111122334444"; |
Az új kódrészletek ezek alapján:
[...] $actual_variation = $rn . $variation; [...] $actual_variation = $variation . $rn; [...] $actual_variation = substr_replace($variation, $rn, $pos + 1, 0); [...] |
A hatodik verzió erőforrásigénye:
Szöveges értelmezésben:
- 1 másodpercen belül kiszámítható: 98 fő
- 30 másodpercen belül kiszámítható: 222 fő
- 25 fő érkező vendég kiszámítása: 0.006 másodperc
- 128MB memórialimit elérése: 257 vendég számításánál
Értékelés: ehhez már adnám a nevem
A hatodik verzió hónapokkal később jött létre, mint – az eredeti kiírást már teljesítő, de még mindig gyerekcipős – második verzió. Ezek alapján úgy gondolom az evolúciója még nem ért véget. Amennyiben a v6-ra úgy tekintünk, mint a “code sapiens”-re, minden valószínűsége megvan a “code sapiens superior” létezésének…
Mivel az első verzió kódja is teljes terjedelmében szerepel, úgy érzem helyesnek, ha a v6 is felkerül (ezúttal kommentek nélkül, mivel szinte minden sora bemutatásra került az előző oldalakon):
<?php $variation_cache = array(0 => array()); function calc_room_use ($passengers, &$variation_cache) { if ($passengers < 1) { return 0; } for ($rn = 1; $rn <= 4; $rn += 1) { if ($passengers >= $rn) { if (! isset($variation_cache[$passengers - $rn])) { calc_room_use($passengers - $rn, $variation_cache); } if (! isset($variation_cache[$passengers])) { $variation_cache[$passengers] = array(); } $actual_variation = $rn; foreach ($variation_cache[$passengers - $rn] as $variation => $devnull) { if ($rn == 1) { $actual_variation = $rn . $variation; } else if ($rn == 4) { $actual_variation = $variation . $rn; } else { for ($lrn = $rn; $lrn > 0; $lrn -= 1) { $pos = strrpos($variation, (string)$lrn); if ($pos !== false) { $actual_variation = substr_replace($variation, $rn, $pos + 1, 0); break; } } } if (! isset($variation_cache[$passengers][$actual_variation])) { $variation_cache[$passengers][$actual_variation] = true; } } if ($passengers == $rn && ! isset($variation_cache[$passengers][$rn])) { $variation_cache[$passengers][$rn] = true; } } } unset($variation_cache[$passengers - 4]); } calc_room_use($passengers, $variation_cache); echo count($variation_cache[$passengers]); ?> |
A következő oldalon pedig a menedzserlelkületűek elégíthetik ki grafikongyűjtemény és táblázat iránti igényeiket.
MySQL jogosultság-szervezés MAC-alapú kivétel Mikrotik hotspot-ba
Comments are currently closed.