Dostęp do dużych tablic w PHP

Robiłem profilowanie różnych metod uzyskiwania dostępu do dużych (ish) tablic danych w PHP. Przypadek użycia jest całkiem prosty: niektóre z naszych narzędzi przesyłają dane do plików PHP jako tablice asocjacyjne, a te pliki są uważane przez aplikację za dane statyczne. Tworzymy gry, więc niektóre przykłady plików danych obejmują elementy w katalogu, zadania, które użytkownik musi wykonać, lub definicje map:

<code><?php
$some_data = array(
    ...lots and lots of stuff in here...
);
?>
</code>

Ponieważ te macierze są duże (400K), a większość naszego kodu jest zainteresowana tymi danymi, konieczne staje się uzyskanie dostępu do tych danych tak efektywnie, jak to możliwe. Postanowiłem wykonać 3 różne wzorce. Po przedstawieniu metod przedstawię poniżej moje wyniki.

To, czego szukam, to pewna walidacja oparta na doświadczeniu w zakresie tych metod i ich czasu, a także wszelkich innych metod wypróbowania.

Metoda # 1: funkcja gettera

W metodzie eksporter faktycznie tworzy plik, który wygląda jak:

<code><?php
function getSomeData()
{
    $some_data = array(
        ...lots and lots of stuff here...
    );
    return $some_data;
}
?>
</code>

Kod klienta może następnie pobrać dane, po prostu wywołując metodę getSomeData (), gdy tego chcą.

Metoda # 2: global + include

W tej metodzie plik danych wygląda identycznie jak oryginalny blok kodu powyżej, jednak kod klienta musi przeskoczyć kilka obręczy, aby uzyskać dane w lokalnym zasięgu. Zakłada to, że tablica znajduje się w pliku o nazwie „some_data.php”;

<code>global $some_data; //must be the same name as the variable in the data file...
include 'some_data.php';
</code>

Spowoduje to przeniesienie tablicy $ some_data do zakresu, choć jest to trochę kłopotliwe dla kodu klienta (moja opinia).

Metoda # 3: getter przez odniesienie

Ta metoda jest prawie identyczna z metodą nr 1, jednak funkcja getter nie zwraca wartości, ale raczej ustawia odniesienie do danych.

<code><?php
function getSomeDataByRef($some_data)
{
    $some_data = array(
        ...lots and lots of stuff here...
    );
    return $some_data;
}
?>
</code>

Następnie kod klienta pobiera dane, deklarując zmienną lokalną (nazywaną dowolną) i przekazując ją przez odniesienie do gettera:

<code>$some_data_anyname = array();
getSomeDataByRef(&$some_data_anyname);
</code>
Wyniki

Uruchomiłem więc mały skrypt, który uruchamia każdą z tych metod pobierania danych 1000 razy i uśrednia czas pracy (obliczany przez mikrotim (prawda) na początku i na końcu). Oto moje wyniki (w ms, uruchomione na MacBookPro 2 GHz, 8 GB RAM, wersja PHP 5.3.4):

METODA 1:

AVG: 0,0031637034416199 MAX: 0,0043289661407471 MIN: 0,0025908946990967

METODA 2:

AVG: 0.01434082698822 MAX: 0.018275022506714 MIN: 0.012722969055176

METODA 3:

AVG: 0,00335768699646 MAX: 0,0043489933013916 MIN: 0,0029017925262451

Mimo to wydaje się całkiem jasne, że metoda global + include jest gorsza od pozostałych dwóch, które są „pomijalną” różnicą.

Myśli? Czy czegoś mi kompletnie brakuje? (prawdopodobnie...)

Z góry dziękuję!

questionAnswers(2)

yourAnswerToTheQuestion