2010-06-06 11 views
7

Próbowałem porównać dwie tablice. Korzystanie z array_intersect nie przedstawia żadnych problemów. Gdy używasz array_diff i tablic z ~ 5000 wartości, to działa. Kiedy osiągam ~ 10.000 wartości, skrypt umiera, gdy dojdę do array_diff. Włączenie funkcji zgłaszania błędów nie spowodowało niczego.obsługa dużych tablic z array_diff

Próbowałem tworzyć własną funkcję array_diff:

function manual_array_diff($arraya, $arrayb) { 
    foreach ($arraya as $keya => $valuea) { 
     if (in_array($valuea, $arrayb)) { 
      unset($arraya[$keya]); 
     } 
    } 
    return $arraya; 
} 

źródło: How does array_diff work?

Spodziewam się, że jest mniej wydajny niż oficjalny array_diff, ale może obsłużyć tablice ~ 10000. Niestety, oba array_diffs zawodzą, gdy dojdę do ~ 15,000.

Próbowałem tego samego kodu na innym komputerze i działa dobrze, więc nie jest to problem z kodem lub PHP. Musi być jakiś limit ustawiony gdzieś na tym konkretnym serwerze. Masz pomysł, jak obejść ten limit, zmienić go lub po prostu dowiedzieć się, co to jest?

+0

Z jakimi danymi testowałeś? – Gumbo

+0

Prawdopodobnie dlatego, że ten algorytm to O (N^2). – kennytm

+0

Czy używasz tego w przeglądarce lub wierszu poleceń? – tipu

Odpowiedz

3

Po napotkaniu tego samego problemu, naprawdę liczyłem na odpowiedź tutaj.

Tak więc musiałem znaleźć własną drogę i wymyślić następujący brzydki kludge, który działa dla mnie z tablicami około 50 000 elementów. Opiera się na twojej obserwacji, że array_intersect działa, ale array_diff nie.

Prędzej czy później spowoduje to również przekroczenie limitów zasobów, w takim przypadku konieczne będzie porcjowanie macierzy i radzenie sobie z mniejszymi bitami. Przekroczymy ten most, kiedy do niego dojdziemy.

function new_array_diff($arraya, $arrayb) { 
    $intersection = array_intersect($arraya, $arrayb); 
    foreach ($arraya as $keya => $valuea) { 
     if (!isset($intersection[$keya])) { 
      $diff[$keya] = $valuea; 
     } 
    } 

    return $diff; 
} 
1

W moim php.ini:

max_execution_time = 60  ; Maximum execution time of each script, in seconds 
memory_limit = 32M   ; Maximum amount of memory a script may consume 

mógłby różnice w tych ustawieniach lub alternatywnie w wykonaniu maszynowego być przyczyną problemów? Czy sprawdziłeś dzienniki błędów serwera WWW (jeśli uruchomiłeś to przez jeden)?

+0

Wykonanie zajmuje tylko kilka sekund, więc czas wykonania nie stanowi problemu. Ręczne obniżenie wartości memory_limit na jednym komputerze spowodowało uśmiercenie skryptu. Jednak ustawienie memory_limit wyżej na drugiej maszynie nie rozwiązało problemu. Jeśli jesteś ciekawy, początkowo przyczyną problemu było 40M na komputerze. – burger

+0

OK, a co z dziennikami błędów serwera? –

1

Wspomniałeś, że działa w przeglądarce. Spróbuj uruchomić skrypt za pomocą wiersza poleceń i sprawdź, czy wynik jest inny.