2013-08-08 17 views
5

Mam tablicę wielowymiarową.php wielowymiarowa optymalizacja pętli tablicowych

$count = count($main_array); // 6000+ 

Każdy element wewnątrz głównej tablicy ma około 25 klawiszy

$count_sub_array = count($main_array[0]); // 25 

mam 3000 unikalną wartość dla jednego klucza. tj.

for($i=0; $i< $count; $i++){ 
    if($main_array[$i][$match]){ 
     array_push($unique_array,$main_array[$i][$match]); 
    } 
} 
$unique_array = array_unique($unique_array); // count - 3000 

Chciałbym iterować poprzez każdy element w tablicy i grupować je według unikalnego typu. I również życzę pogrupowanie elementów, jak na jednej z konkretnym indeksem np

$unique_index = array('2012-08','2012-07','2012-06','2012-05','2012-04','2012-03','2012-02', '2012-01'); 

#count unikalnego indeksu w chwili obecnej jest 13

tak, że wynik wygląda tak:

array (size=2689) 
0 => 
array (size=5) 
    'type' => string 'abc' (length=19) 
    'totalCost' => 
    array (size=13) 
     '2012-07-01' => float 790.08 
     '2012-08-01' => float 1501.84 
     '2012-09-01' => float 1568.9 
     '2012-10-01' => float 2756.04 
     '2012-11-01' => float 2428.42 
     '2012-12-01' => float 1901.09 
     '2013-01-01' => float 2538.59 
     '2013-02-01' => float 1537.57 
     '2013-03-01' => float 1674.51 
     '2013-04-01' => float 1141.01 
     '2013-05-01' => float 764.24 
     '2013-06-01' => float 1179.84 
     '2013-07-01' => float 1252.66 
    'numOrders' => 
    array (size=13) 
     '2012-07-01' => int 16 
     '2012-08-01' => int 66 
     '2012-09-01' => int 65 
     '2012-10-01' => int 59 
     '2012-11-01' => int 60 
     '2012-12-01' => int 47 
     '2013-01-01' => int 85 
     '2013-02-01' => int 50 
     '2013-03-01' => int 46 
     '2013-04-01' => int 41 
     '2013-05-01' => int 22 
     '2013-06-01' => int 32 
     '2013-07-01' => int 47 
    'TotalRevenue' => 
    array (size=13) 
     '2012-07-01' => float 1695.99 
     '2012-08-01' => float 7418.17 
     '2012-09-01' => float 7827.99 
     '2012-10-01' => float 7929.63 
     '2012-11-01' => float 4815.74 
     '2012-12-01' => float 5592.59 
     '2013-01-01' => float 6874.02 
     '2013-02-01' => float 11599.49 
     '2013-03-01' => float 10358.57 
     '2013-04-01' => float 6909.55 
     '2013-05-01' => float 6983.38 
     '2013-06-01' => float 7211.84 
     '2013-07-01' => float 10422.59 
    'profit' => 
    array (size=13) 
     '2012-07-01' => float 905.91 
     '2012-08-01' => float 5916.33 
     '2012-09-01' => float 6259.09 
     '2012-10-01' => float 5173.59 
     '2012-11-01' => float 2387.32 
     '2012-12-01' => float 3691.5 
     '2013-01-01' => float 4335.43 
     '2013-02-01' => float 10061.92 
     '2013-03-01' => float 8684.06 
     '2013-04-01' => float 5768.54 
     '2013-05-01' => float 6219.14 
     '2013-06-01' => float 6032 
     '2013-07-01' => float 9169.93 
1 => 
array (size=5) 
    'type' => string 'bcd' (length=26) 
    'totalCost' => 
    array (size=13) 
     '2012-07-01' => float 599.53 
     '2012-08-01' => float 419.18 
     '2012-09-01' => float 212.63 
     '2012-10-01' => float 462.55 
     '2012-11-01' => float 450.08 
     '2012-12-01' => float 447.1 
     '2013-01-01' => float 657 
     '2013-02-01' => float 734.68 
     '2013-03-01' => float 1006.91 
     '2013-04-01' => float 1497.95 
     '2013-05-01' => float 2100.96 
     '2013-06-01' => float 3845.33 
     '2013-07-01' => float 6817.38 
    'numOrders' => 
    array (size=13) 
     '2012-07-01' => int 11 
     '2012-08-01' => int 33 
     '2012-09-01' => int 25 
     '2012-10-01' => int 28 
     '2012-11-01' => int 33 
     '2012-12-01' => int 28 
     '2013-01-01' => int 33 
     '2013-02-01' => int 45 
     '2013-03-01' => int 54 
     '2013-04-01' => int 53 
     '2013-05-01' => int 69 
     '2013-06-01' => int 91 
     '2013-07-01' => int 180 
    'TotalRevenue' => 
    array (size=13) 
     '2012-07-01' => float 1201.32 
     '2012-08-01' => float 4889.65 
     '2012-09-01' => float 2171.5 
     '2012-10-01' => float 2573.75 
     '2012-11-01' => float 2375.1 
     '2012-12-01' => float 2807.28 
     '2013-01-01' => float 2933.05 
     '2013-02-01' => float 5534.61 
     '2013-03-01' => float 6946.02 
     '2013-04-01' => float 8555.78 
     '2013-05-01' => float 8202.32 
     '2013-06-01' => float 14140.04 
     '2013-07-01' => float 22043.54 
    'profit' => 
    array (size=13) 
     '2012-07-01' => float 601.79 
     '2012-08-01' => float 4470.47 
     '2012-09-01' => float 1958.87 
     '2012-10-01' => float 2111.2 
     '2012-11-01' => float 1925.02 
     '2012-12-01' => float 2360.18 
     '2013-01-01' => float 2276.05 
     '2013-02-01' => float 4799.93 
     '2013-03-01' => float 5939.11 
     '2013-04-01' => float 7057.83 
     '2013-05-01' => float 6101.36 
     '2013-06-01' => float 10294.71 
     '2013-07-01' => float 15226.16 
); 

Jak mogę zoptymalizować pętlę?

Obecnie mam następującą logiką:

1. get the main array from mysql 
2. get unique elements 
3. foreach unique element 
     a. foreach key like '2013-06-01', '2013-07-01' 
     b. foreach main array 
       match above key i.e. if($time == '2013-06-01') 
     c. get $value['totalCost'], $value['numOrders'], $value['profit'], value['revenue'] 

Jak na mnie, złożoność tej pętli: 3000 * 13 * 6000;

Dzięki za pomoc z góry.

+0

Wspomniałeś, że dane pochodzą z SQL, czy próbowałeś dokonać grupowania i przetwarzania w kwerendzie bazy danych? –

+0

Tak, jest już zgrupowane, dlatego musiałem uzyskać unikalną tablicę, aby utworzyć tablicę w powyższej strukturze. – Gaurav

+0

Po długim spoglądaniu na twój przykład wciąż nie jestem pewien, jak wyglądają twoje początkowe dane (w bazie danych).Gdybym wiedział, lub przynajmniej miałby lepszy przykład tego, jak wygląda twój zestaw wyników (początkowa tablica), wierzę, że mógłbym napisać kwerendę sql, która pozwoli napisać twoją macierz wyjściową w jednej pętli z jedną warunkową witin tą pętlą. Ponieważ nie potrzebujesz w ogóle kroków 2 i 3a, a całe 3 jest tylko raz 3.b, ale z mądrzejszym dopasowaniem – Konstantin

Odpowiedz

0

Musisz wykonać pętlę trzy razy, ale dobrze wybierz swoje pętle.

Ponieważ główna tablica jest największa, chcesz ją zapętlić tylko raz. Zamiast budować najpierw tablicę dat, budujesz i wypełniasz ją, przechodząc przez główną tablicę.

  1. dostać główną tablicę z mysql
  2. pętli tylko raz

    $dates = array(); 
    $measures = array(
        'totalCost' => 0, 
        'numOrders' => 0, 
        'TotalRevenue' => 0, 
        'profit'  => 0 
    ); 
    foreach ($main as $main_element) { 
        foreach (array_keys($measures) as $measure) { 
         foreach ($main_element[$measure] as $date => $value) { 
          if(!isset($dates[$date])) { 
           $dates[$date] = $measures; 
          } 
          $dates[$date][$measure] += $value; 
         } 
        } 
    } 
    

Uwaga: W zależności od swoich preferencji dotyczących struktury wyniku, można zastąpić

$dates[$date][$measure] 

przez

$dates[$measure][$date] 

Nadal masz 3 pętle, ale tylko pętlę 6000 * 4 * 13 razy, co jest znacznie lepsze.

+0

Dzięki. ale to nie znaczy, mam unikalną tablicę. Od 6000 iteracja jest główną pętlą, a 3000 to unikalne rozwiązanie. teraz muszę zgrupować unikatowe elementy we wspomnianej modie .. co oznacza .. 3000 razy muszę znaleźć dla każdej daty i wartości kombinacji miary z głównej tablicy jeszcze przypisać 0 jako wartość – Gaurav

+0

To właśnie robię. Czy możesz podać strukturę tabeli wyników? Pomoże mi to zrozumieć, w którym punkcie moje rozwiązanie nie jest wystarczające. –

+0

Dzięki. Zoptymalizowałem cały proces za pomocą memcache. Wkrótce opublikuję dla ciebie próbną tablicę. Znosisz mnie do tego czasu. – Gaurav

0

Użyłem memcached rozszerzenie php, aby rozwiązać problem. Przy pierwszym wyniku zajmuje zwykle czas, jednak później działa szybciej, gdy klucz pamięci podręcznej zostanie znaleziony na memcached serwerze.