2010-02-22 15 views
12

Oto mój kod, który tworzy tablicę 2d wypełniony zerami, wymiary tablicy są (795,6942):Problemy z PHP podczas próby utworzenia dużą tablicę

function zeros($rowCount, $colCount){ 
    $matrix = array(); 
    for ($rowIndx=0; $rowIndx<$rowCount; $rowIndx++){ 
     $matrix[] = array(); 
     for($colIndx=0; $colIndx<$colCount; $colIndx++){ 
      $matrix[$rowIndx][$colIndx]=0; 
     } 
    } 
    return $matrix; 
} 

$matrix = zeros(795,6942); 

I tu jest błąd, że otrzymują:

Allowed memory size of 134217728 bytes exhausted (tried to allocate 35 bytes) 

Wszelkie pomysły na rozwiązanie tego problemu?

+0

Ponieważ w pamięci tworzona jest tablica wypełniona zerami, zakładam, że chcesz wykonać niektóre operacje na tym. W takim przypadku, dlaczego nie używasz datastore takiego jak Redis? Będzie zawierał ogromne dane z niewielkim obciążeniem dla php. Możesz uruchamiać operacje z pomijaną pułapką wydajności. – mixdev

Odpowiedz

27

W szybkiej kalkulacji, staramy się stworzyć tablicę, która zawiera:

795*6942 = 5,518,890 

całkowitymi.

Jeśli przyjmiemy, że liczba całkowita jest przechowywana w 4 bajty (to znaczy 32-bitowe, PHP, to nie może być mniejsza), to znaczy:

5518890*4 = 22,075,560 

bajtów.

OK, szybkie obliczenia ... wynikiem jest "powinno być OK".

Ale sprawy nie są takie proste, niestety :-(
Przypuszczam, że to związane z faktem, że dane są przechowywane przez PHP przy użyciu wewnętrznego danych struktura, która jest znacznie bardziej skomplikowany niż zwykły 32 bitów całkowitych


teraz, żeby być ciekawy, zmieńmy swoją funkcję tak wyprowadza ile pamięci stosowany jest na końcu każdego z zewnętrznej for -loop:

function zeros($rowCount, $colCount){ 
    $matrix = array(); 
    for ($rowIndx=0; $rowIndx<$rowCount; $rowIndx++){ 
     $matrix[] = array(); 
     for($colIndx=0; $colIndx<$colCount; $colIndx++){ 
      $matrix[$rowIndx][$colIndx]=0; 
     } 
     var_dump(memory_get_usage()); 
    } 
    return $matrix; 
} 

Dzięki temu otrzymuję tego rodzaju wyjście (PHP 5.3.2-dev na systemie 64-bitowym; memory_limit jest ustawiony na 128MB - co jest już dużo):

int 1631968 
int 2641888 
int 3651808 
... 
... 
int 132924168 
int 133934088 
Fatal error: Allowed memory size of 134217728 bytes exhausted 

Czyli każdej iteracji zewnętrznej for -loop wymaga czegoś podobnego 1,5 MB pamięci - a ja się tylko do 131 iteracji wcześniej! w skrypcie zabraknie pamięci; a nie 765, jak chciałeś.

Biorąc pod uwagę tak ustawić memory_limit do 128M, trzeba by ustawić go do czegoś naprawdę dużo wyższa - jak

128*(765/131) = 747 MB 

dobrze, nawet z

ini_set('memory_limit', '750M'); 

to wciąż za mało. ..z 800MB wydaje tyle ;-)


Ale nie Zdecydowanie polecam ustawienie memory_limit do tak wysokiej wartości!

(Jeśli masz 2 GB pamięci RAM, twój serwer nie będzie w stanie obsłużyć więcej niż 2 jednoczesnych użytkowników ^^ ;, nie przetestowałbym tego, jeśli mój komputer miał 2 GB pamięci RAM, szczerze mówiąc)


jedynym rozwiązaniem widzę tutaj jest, aby ponownie przemyśleć swój projekt: musi istnieć coś jeszcze można zrobić, niż korzystać z tej części kodu :-)

(BTW: może " ponownie przemyśl swój projekt "oznacza używanie innego języka PHP: PHP jest świetne, jeśli chodzi o tworzenie stron internetowych, ale nie jest odpowiednie dla każdego rodzaju problemu)

1

Należy spróbować zwiększyć ilość pamięci dostępnej dla PHP:

ini_set('memory_limit', '32M'); 

w pliku PHP.

+2

Domyślnie ustawiono 128M – spacemonkey

5

Domyślna implementacja macierzy PHP wymaga dużej ilości pamięci. Jeśli tylko przechowujesz liczby całkowite (i wiele z nich), prawdopodobnie chcesz spojrzeć na SplFixedArray. Używa zwykłego, ciągłego bloku pamięci do przechowywania danych, w przeciwieństwie do tradycyjnej struktury hash.

Powiązane problemy