2010-11-19 15 views
25

Oznacza to, że lepiej byłoby użyć jakiejś struktury danych drzewiastych lub pominiętych list, jeśli muszę wywoływać tę funkcję dużo dla wstawiania pojedynczych macierzy?JavaScript: Jakie jest algorytmiczne działanie "splice"?

+0

testowy to! To najlepszy sposób, aby odpowiedzieć na to pytanie ... – Harmen

+0

Jaki jest dobry sposób na sprawdzenie tego? – Hamster

+0

Jeśli tablice JavaScript są w rzeczywistości tablicami, jest to O (n). – Gumbo

Odpowiedz

15

Możesz rozważyć, czy zamiast tego chcesz użyć prostej mapy; wszystkie obiekty JavaScript (łącznie z instancjami Array) są mapami, więc implementacja powinna być (proszę zauważyć, że nie mówię "nie") ma rozsądny algorytm mieszający wydajność.

Oprócz tego wydajność splice będzie się różnić część między implementacjami (np. Dostawców). Jest to jeden z powodów, dla których "nie optymalizuj przedwcześnie" jest jeszcze bardziej odpowiednią radą dla aplikacji JavaScript, które będą działać w wielu implementacjach dostawców (na przykład aplikacje internetowe), nawet w przypadku normalnego programowania. Dbaj o to, aby kod był dobrze zmodularyzowany i rozwiązywał problemy z wydajnością, jeśli wystąpią.

+1

Problem z mapą nie wydaje mi się, żebym mógł ją powtórzyć w uporządkowanej kolejności ... – Hamster

+1

@Hamster: Możesz, ale tylko znajdując wszystkie klucze, sortując je, a następnie przeglądając tę ​​listę. Jeśli musisz to zrobić dużo, to prawdopodobnie lepiej Ci się z 'Tablicą' (która w JavaScript jest przecież po prostu mapą o zdefiniowanej kolejności i magiczną właściwością' length'). –

+0

@ T.J.Crowder Co się stanie, jeśli będę musiał wstawiać element w określonym indeksie między już istniejącymi elementami (tj. Utrzymywać je i porządkować indeksy) często, a są tysiące elementów? Wiem, że mogę to zrobić za pomocą 'splice', ale jest' Array' z 'splice' odpowiednią strukturą danych dla takiego zadania? Jeśli nie, to jaka inna struktura danych JS może nadawać się do tego? – tonix

7

Oto dobra zasada, oparta na testach przeprowadzonych w Chrome, Safari i Firefox: Łączenie pojedynczej wartości w środek tablicy to w przybliżeniu o połowę szybsza jako przesuwanie/przesuwanie wartości do jednego z końców szyk. (Uwaga: Tylko testowany na tablicy wielkości 10,000.)

http://jsperf.com/splicing-a-single-value

To dość szybko. Jest więc mało prawdopodobne, że musisz zająć się wdrażaniem kolejnej struktury danych w celu wyciśnięcia większej wydajności.

Aktualizacja: Jak eBusiness zwraca uwagę w komentarzach poniżej, badanie wykonuje kosztowną operację kopiowania wraz z każdym splice, push i shift, co oznacza, że ​​nie docenia różnicy w wydajności. Oto poprawiony test, który zapobiega kopiowaniu tablicy, więc powinno być znacznie bardziej precyzyjne: http://jsperf.com/splicing-a-single-value/19

+1

W rzeczywistości zależy to całkowicie od długości tablicy. Jeśli zmienisz tablicę na 100 000 elementów, to łączenie wartości w środku jest o 95% wolniejsze niż dodanie wartości na końcu, jak zmierzono w teście jsperf. To dlatego, że wstawienie w środku to O (n) w rozmiarze tablicy, podczas gdy wstawienie na końcu może być O (1). – Geoff

+3

-1 Ten test jsperf jest zanieczyszczony przez skopiowanie tablicy, w większości chodzi o pomiar czasu potrzebnego na utworzenie całej nowej tablicy 10000 elementów. – aaaaaaaaaaaa

+0

@eBusiness Proszę opracować swoje roszczenie. Gdzie w testach tablica jest kopiowana? –

-1

Move pojedyncza wartość

// \t tmp = arr[1][i]; 
 
// \t arr[1].splice(i, 1); \t // splice is slow in FF 
 
// \t arr[1].splice(end0_1, 0, tmp); 
 

 
\t tmp = arr[1][i]; 
 
\t ii = i; 
 
\t while (ii<end0_1) 
 
\t \t { 
 
\t \t arr[1][ii] = arr[1][++ii]; 
 
cycles++; 
 
\t \t } 
 
\t arr[1][end0_1] = tmp;

Powiązane problemy