2010-09-14 13 views
12

Powiel możliwe:
When should I use stdClass and when should I use an array in php5 oo code ??Używanie tablic VS obiektów do przechowywania danych

Jakie są zalety korzystania z jednego z dwóch struktur nad innymi?

// array 
$user['name'] = 'Emanuil'; 

// object 
$user->name = 'Emanuil'; 
+2

Dlaczego mówisz, że 1 jest lepszy niż 2? Osobiście nie zgadzam się z tym stwierdzeniem. Czy możesz wyjaśnić, dlaczego uważasz, że 1 jest lepszy niż 2? Czy mówimy o wydajności, zużyciu pamięci, praktyce kodowania? Zajrzyj na: http://particletree.com/notebook/object-oriented-php-memory-concerns/. – Chris

+0

Wskazówka: może tablice zużywają mniej zasobów. – fabrik

+0

@ Chris: Myślę, że przeczytałem gdzieś, że jeśli potrzebujesz struktury do przechowywania danych, to 1 jest preferowaną drogą. –

Odpowiedz

27

Tablice

  • Istnieje ton od array_* funkcji, które mogą pracować na tablicach, z których większość jest bardzo szybki.
  • one domyślnie przechodzi przez wartość (skopiowany wokół)
  • Lekkie/proste (zmienia się tylko efekt zmiennej lokalnej, oszczędzając około myślę)
  • często wykorzystywane do produkcji po danych (danych, który nie zmienia się)
  • Wszystkie dane są publiczne
  • Lekko mniej zasobów intensywne

Przedmioty

  • Można zastosować metody, aby dane były bardziej rygorystyczne. (TO ZNACZY.Kontrole że pole uniwersalny format)
  • Utworzenie podklasy (zmniejszenie kod powielanie)
  • Domyślnie są one przekazywane przez referencję
  • Zmiany danych może mieć efekt kaskadowy (__get, __set, itp)
  • często wykorzystywane do dane, które jest bardziej zmienny
  • może chronić dane z zewnątrz za pomocą funkcji i chroniony/zmienne prywatne
  • Funkcja podpowiedzi typu obiektów jest bardziej elastyczny (inna typehint dla różnych klas)
6

Wystarczy uruchomić prosty test:

$ts_o = microtime(true); 
for($i=0;$i<=1000;$i++) 
{ 
    new stdClass(); 
} 
$total_object = microtime(true) - $ts_o; 

Versus:

$ts_a = microtime(true); 
for($i=0;$i<=1000;$i++) 
{ 
    array(); 
} 
$total_array = microtime(true) - $ts_a; 

i obliczyć jego wyniki.

echo 'Object: ' . $total_object . '/Array: ' . $total_array; 

Wyniki: obiektu: 0,002635/Array: 0,001243

Jak widać, że tablice są szybsze w odniesieniu do prędkości, średniej 46,6% Rzeczywistą.

Ale kiedy rozpocząć dodawanie zmiennych nagle zawrócić:

$ts_o = microtime(true); 
for($i=0;$i<=1000;$i++) 
{ 
    $var = new stdClass(); 
    $var->booleon = true; 
} 
$total_object = microtime(true) - $ts_o; 
unset($var); 

$ts_a = microtime(true); 
for($i=0;$i<=1000;$i++) 
{ 
    $var = array(); 
    $var['booleon'] = true; 
} 
$total_array = microtime(true) - $ts_a; 

echo 'Object: ' . ($total_object) . '/Array: ' . $total_array; 

Nowe Wyniki: 0,0037809/Array: 0,0046189

Istnieje kilka testy trzeba by zrobić, a następnie znaleźć swoją średnią/tryb na końcu testu, aby znaleźć ten, który naprawdę jest lepszym bytem.

Możesz wykonać test pamięci, wykonując memory_get_usage: http://php.net/manual/en/function.memory-get-usage.php z tymi samymi zasadami.

+8

Rozważania dotyczące wydajności IMO nie powinny wpływać na decyzję, czy użyj jednego lub drugiego. – Gordon

+1

Przetestuj pisanie do nich. Przetestuj przekazywanie ich do funkcji. Przetestuj przekazywanie przez odniesienie i modyfikuj je wewnątrz funkcji (wskazówka, z obiektami, których nie musisz przekazywać przez odniesienie do modyfikacji wewnątrz funkcji). Tworzenie jest prawdopodobnie najrzadziej wykonywane z tablicami lub obiektami. Kogo to obchodzi, jeśli są tanie w tworzeniu, jeśli są drogie w użyciu ... A poza tym mówisz o różnicy "1x10^-6" ... Jeśli martwisz się tym małym zyskiem, marnujesz swój czas. Pamiętaj, że "Przedwczesna optymalizacja jest korzeniem wszelkiego zła" ... – ircmaxell

+0

Jednak ogólna wydajność jest główną częścią każdej udanej aplikacji i powinna być adresowana za każdym razem, gdy zostanie podana decyzja/implementacja! – RobertPitt

5

Co robisz? Żadna struktura nie jest lepsza we wszystkim, dlatego oba istnieją. To naprawdę zależy od twojego zestawu problemów, który jest "lepszy". I nawet wtedy może to być po prostu przypadek, który wolisz. Wiele projektów architektury i kodu to osobiste preferencje i styl.

Ogólnie rzecz biorąc, istnieje tylko jeden raz, gdy użyłbym obiektu bez metody (stdclass lub zdefiniowanego przez użytkownika) nad tablicą. To znaczy, jeśli muszę bardzo dużo przekazywać te dane i modyfikować je w wielu miejscach. Z tablicą musisz przekazać ją przez referencję, co jest uciążliwe i może wprowadzić źródła błędu ... Z obiektem jest on przekazywany domyślnie jako odniesienie do obiektu (nie jako odniesienie do zmiennej, ale jako wskaźnik do tego samego obiekt). Więc z tablicy trzeba by zrobić coś takiego:

function doSomething($inVar, array &$inOutArray) { 
    $inOutArray['bar'] = 'baz'; 
} 

dla każdej funkcji, która modyfikuje (lub może modyfikować) tablicę.

Podczas gdy z obiektu, można po prostu zrobić:

function doSomething($inVar, $object) { 
    $object->bar = 'baz'; 
} 

Jest krótszy (pamiętaj, tylko jedna postać, ale jest to jeden znak wszędzie może chcesz zmodyfikować tablicę). To mniej podatne na błędy, ponieważ jeśli później zrobić $object = new Something(), to nie zmieni oryginalnego obiektu (ponieważ nie jest zmienna referencyjna) ...

Jedynym argumentem jest to, że nieco mniej czytelne, ponieważ & pokazach wyraźnie, że zamierzasz zmodyfikować tę zmienną wejściową. Ale jeśli rozumiesz, jak działają obiekty w PHP 5, nie powinieneś być zaskoczony (a więc jest to akceptowalna kompromitacja w moim umyśle) ...

Powiązane problemy