piątek, 14 października 2011

Array vs Object

Tak jakoś nastał obiektowy szał i wszystko wszędzie musi być obiektowe. Oczywiście PHP ta mania nie ominęła i tak oto mamy coraz to większą społeczność krzyczących, że Object i Class jest super fajne, a Array to zło i anachroniczny przeżytek. Ale czy jest tak na pewno?
Oczywiście tablice nie pozwalają na implementacje funkcji odwołujących się jedynie do danych z konkretnej tablicy - takie coś musimy zrealizować poprzez metodę jakiejś klasy lub po prostu funkcję nie należącą do żadnej klasy (co oczywiście jest mało eleganckie). Jednak jeśli zależy nam jedynie na przechowaniu tudzież przekazaniu danych z jednej funkcji do drugiej to czy warto definiować nowy typ danych (zakładając, że struktura danych nigdy nie ulegnie zmianie)? W innych językach programowania w 99% przypadków odpowiedź brzmiała by "tak", jednak w przypadku PHP nie jest ona wcale taka oczywista.

Dlaczego? Ano załóżmy, że chcemy przesłać dane dotyczące elementu opisywanego za pomocą trzech atrybutów (id, name, color). Przykładowy kod realizujący takie zadanie wyglądałby następująco:
function getArray()
{
 $item = Array();
 $item['id'] = 1;
 $item['name'] = "Pure item";
 $item['color'] = "none";
 return $item;
}
 
function getObject()
{
 $item = new stdClass();
 $item->id = 1;
 $item->name = "Pure item";
 $item->color = "none";
 return $item;
}
function getItem()
{
 $item = new Item();
 $item->id = 1;
 $item->name = "Pure item";
 $item->color = "none";
 return $item;
}
Dla ostatniej funkcji konieczne jest zdefiniowanie typu "Item":

class Item
{
    public $id;
    public $name;
    public $color;
}

Wykonanie tych funkcji jak widać tworzy struktury o tych samych atrybutach - raz jest to tablica, a w dwóch przypadkach są to instancje klas.
getArray      0.1664547920
getObject      0.2381231785
getItem       0.2375209332
Jak widać stworzenie i zapełnienie tablicy trwa ok. 70% czasu potrzebnego na utworzenie odpowiadającej jej klasie. Warto zauważyć, że czasy potrzebne na utworzenie instancji obiektu za pomocą zdefiniowanej klasy (Item) jak i użycia stdClass() są porównywalne.

A jak przedstawia się proces pobierania wartości z tych trzech utworzonych struktur danych?
Acquire from Array     1.7432529926
Acquire from Object     2.1544189453
Acquire from Item     2.3280811310
Znów nie ma większych zaskoczeń- używanie tablic okazuje się o wiele szybsze niż zaprzęganie klas. Co ciekawe pobieranie danych z instancji utworzonych za pomocą stdClass() okazuje się szybsze (choć nieznacznie) od pobierania wartości atrybutów z klas zdefiniowanych przez użytkownika.

Wnioski
To co chciałem pokazać w tym wpisie to to, że nie warto bezkrytycznie podchodzić do obecnych "trendów". Jeśli potrzebujemy maksymalnie wydajnego sposobu na przekazanie zestawu danych z jednego miejsca w programie do drugiego - to definiowanie klas mija się z celem. Oczywiście jeśli chcemy by nasz kod był maksymalnie przenośny to warto (a wręcz należy) użyć klas - ale tych definiowanych przez użytkownika. Wszak po to tworzymy definicję struktury klasy aby móc dołączyć do niej metody, a w przypadku używania stdClass otrzymujemy (pod względem czystej funkcjonalności) tablicę, która w dodatku działa wolniej od tej "standardowo" tworzonej za pomocą Array().

Plik z testami do pobrania z chomika (link).

Brak komentarzy:

Prześlij komentarz