Objektum-orientált időmérő készítése

Tegyük szívünkre a kezünket, ugye veletek is megesett már, hogy reggel egy verítékben úszó ágyban ébredtetek, miután a php_max_execution_time-ról álmodtatok. Ez az amitől minden programozó retteg, olyan ez számunkra mint rabnak a börtön rácsa, vagy mint birkáknak a villanypásztor. Ez az a php-beállítás ugyanis, ami beszabályozza nekünk, hogy szkriptjeink mennyi ideig futhatnak. És sajnos az esetek többségében nincs más megoldás, mint odaülni kedvenc szövegszerkesztőnk elé, és vért izzadva megkeresni a “bűnös” kódrészt, ami lelassítja kódunk működését. Aztán egy-két ilyen alkalom után rájövünk, hogy van megoldás a bajunkra, dolgozhatna helyettünk a php is, hiszen egy egyszerű stopperrel megoldható, hogy kiszúrjuk a “csigázó” kódrészt és kigyomláljuk azt a kódunkból.

Stopper osztály készítése

Szóval ebben a kis segédletben egy rugalmasan használható stoppert fogunk készíteni, ami most kivételesen nem a 4 x 100m-es vegyes váltó részidejét fogja mérni, hanem szkriptünk futási idejét. Nagyon fontos, hogy a stopper OOP rendszerben (Object Oriented Programming – Objektum Orientált Programozás) fog készülni, amit most nem kívánnék részletezni, elég annyit tudni róla, hogy ez teszi lehetővé, hogy a jövőben stopperünkből korlátlan számú példány fusson egy szkripten belül.

Az első lépés az legyen, hogy nyitunk egy új szövegfájlt, majd elmentjük timer.php néven. A fájl tartalma legyen a következő:

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
class sajatStopper {
var $kezdo_ido; 
var $befejezo_ido; 
// Konstruktor
function sajatStopper() { 
$this->kezdo_ido = microtime(); 
return true; 
} 
// Megállitja a stoppert
function stopperAllj() { 
$this->befejezo_ido = microtime(); 
return true; 
} 
// Kiírja a mért időt 
function stopperMutasd($tizedes=3) { 
$tizedes = intval($tizedes); 
if ($tizedes > 8) 
$tizedes = 8; 
if ($tizedes < 0) 
$tizedes = 0; 
$befejezo_ido = explode(" ", $this->befejezo_ido); 
$befejezo_ido = (float)$befejezo_ido[1] + (float)$befejezo_ido[0]; 
$kezdo_ido = explode (" ", $this->kezdo_ido); 
$kezdo_ido = (float)$kezdo_ido[1] + (float)$kezdo_ido[0]; 
return number_format($befejezo_ido - $kezdo_ido, $tizedes); 
} 
// Megállítja a stoppert és kiírja a mért időt 
function stopperMutatAll($tizedes=2) { 
$this->stopperAllj(); 
return $this->stopperMutasd($tizedes); 
} 
}

Nézzük most végig a programot

Az első sorban a class szó után megadjuk az osztály nevét, ami jelen esetben sajatStopper névre hallgat. Ez az osztály képezi majd időmérő objektumunk alapját, valahányszor szeretnénk majd egy új stoppert indítani, ezt az osztályt kell majd meghívni. A nevét később átírhatod másra is, de egyelőre hagyd így, az okokat pár sorral lentebb megtalálod.

Az azt követő két sor Pascalban vagy C-ben programozóknak nem lesz ismeretlen, két változót fogunk definiálni. (Vigyázz: itt OOP-ben programozunk, procedúra alapú programozásnál nem kell definiálni semmiféle változót a php-ben!)

Aztán a következő érdekes rész egy funkció, ezt a funkciót nevezzük konstruktornak. A konstruktor különlegessége, hogy mindannyiszor lefut, ahányszor meghívjuk az osztályt. Ezt a sajátosságot ki is használjuk, mégpedig arra, hogy elindítsuk stopperünket, a $this->kezdo_ido = microtime(); paranccsal. Az ok, ami miatt arra kértelek, hogy még ne nevezd át az osztályt az, hogy a konstruktornak és az osztálynak azonos nevűnek kell lennie. Magyarán, ha azt akarod, hogy az osztályod neve az legyen, hogy “Bela_stoppere” akkor a konstruktor első sorát is le kell cserélned, valahogy így:

1
function Bela_stoppere () {

(PHP 5 alatt már a __construct() név használandó a konstruktoroknál. További információ a PHP-beli OOP lehetőségekről – BlackY)

A második funkció megállítja a stoppert, magyarán szólva feljegyzi a parancs kiadásának időpillanatát.

A harmadik funkció már érdekesebb, ez végzi a lényegi működést, vagyis írja ki a mért időt. Nem csak ennyi a feladata azonban, hanem ez végzi a mért idő számítását is, mégpedig úgy, hogy kivonja egymásból a stopper megállításának és indításának idejét. A svédcsavar az explode-dal azért kell, mert a fentebb az idő meghatározására használt microtime függvény kimenetét először használható formátumra kell hozni. Ezt most nem részletezném, elég róla ennyit tudni.

Végül a negyedik funkció, amelynek működése triviális, először meghívja a második funkciót, majd pedig a harmadikat, ezzel megállítja a stoppert és megjeleníti az eredményt. Persze felmerülhet benned, hogy mi a fenének kódoltunk le két külön funkciót, ha egy harmadikban úgyis egyszerre hívjuk meg őket. A válasz egyszerű: azért, mert előfordulhat, hogy a stopper eredményét nem ott és nem akkor akarod megjeleníteni, amikor azt megállítottad. Például, ha a kód közepéig szeretnéd mérni az eltelt időt és csak a lap alján szeretnéd kiírni, hogy mennyi is lett az eredmény.

Használat

Akik idáig unatkozva és a körmüket reszelve olvastak, azok most kapják fel a fejüket, mert jön a legszaftosabb rész, a használat. Adott ugye egy kód, amiben mérni akarjuk az időt. Kezdetnek illesszük be a következő sort a mérendő php fájl legtetejére:

1
include ('timer.php');

Ez feltételezi azt, hogy az előbb elkészített timer.php ugyanabban a könyvtárban van, mint amiben a mérendő szkript. Ha még nincs, akkor javaslom, hogy gyorsan másold be! (Az egész nincs 3 kilobyte szóval nem fogsz belehalni!)

Miután ez megvan, akár közvetlenül e sor alá írd be a következő sort:

1
$stopper1 = new sajatStopper ();

Ezzel létrehoztál egy új stopper-objektumot és egyben el is indítottad azt. A következő lépés az legyen, hogy valahol megállítod a stoppert. Az egyszerűség végett ez a hely legyen most valahol a fájl legvégén. A megállítás így történik:

1
$stopper1->stopperAllj()

Most tehát már befejeződött a mérés, nincs más hátra mint kicsalogatni objektumunkból az eredményt és kiírni azt. Erre használjuk az echo() parancsot.

1
echo ('A szkript futásának ideje: ' . $stopper1->stopperMutasd());

Ha minden jól megy, a szkripted kimenetének végén ott fog figyelni egy gusztusos kis mért idő, amiből aztán levonhatod a következtetéseket. Tartozom még néhány aprósággal.

Azt már említettem, hogy a stopperből korlátlan példány futhat. Ezt megoldani szintén egyszerű, nézd csak:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
include ('timer.php'); // Beolvassuk a timer.php-t
 
$stopper1 = new sajatStopper();
$stopper2 = new sajatStopper();
for ($i =0; $i <= 100; $i++) {
echo ('<small>Tutorial.hu</small>');
}
$stopper1->stopperAllj();
for ($i =0; $i <= 100; $i++) {
echo ('<small>Gyik.com</small>');
}
$stopper2->stopperAllj();
 
echo('Az egész program futási ideje: ' . $stopper2->stopperMutasd(); . '<br />');
echo('A Tutorial.hu feliratot ennyi idő alatt írtam ki: ' . $stopper1->stopperMutasd(); . '<br />');

Ha alaposabban megnézed, akkor a stopperMutasd() funkciónál meg lehet adni, hogy hány tizedesjegyig írja ki az eredményt. Egyszerűen csak írj be egy számot (1 és 8 között) a függvény neve utáni zárójelbe, így:

1
stopperMutasd(4);

Zárszó

Hát ennyi volna ez a kis segédlet. Persze lehetett volna bonyolítani még a dolgokat, például megoldhattuk volna, hogy a mért eredményeket a program ne csak kiírja, de mentse is őket egy adatbázisba vagy egy fájlba, sőt egy kis trükközéssel az adott idő alatt feldolgozott adatmennyiséget is mérhettük volna, de nem tettük, mert a cél egy egyszerű időmérő készítése volt. Ha valakinek mégis szüksége van ezekre a funkciókra, akkor ugorjon neki, hiszen az alapja már megvan! Minden észrevételt, amit ezzel a kóddal kapcsolatos, szívesen fogadok a linkinparkhu (qkac) gmail (pont) com email címen!

Szerző: BonD

3 HOZZÁSZÓLÁS

  1. to: blase

    valóban mert a szerző egy helyen helytelenül irta a kodot.
    Abba a file-ba ahol használni (mérni) akarod

    1
    
    echo ('A szkript futásának ideje: ' . $stopper1->stopperMutasd);

    helyett

    1
    
    echo ('A szkript futásának ideje: ' . $stopper1->stopperMutasd());

    (a végén a két zárójel lemardt)

  2. hát igen a copy+past az ilyen.

    köszi a cikket. Hasznos volt az OOP(objektum orientált programozás) mélyebb megismeréséhez.

HOZZÁSZÓLOK A CIKKHEZ

Kérjük, írja be véleményét!
írja be ide nevét