Tablice a wydajność

Tablice a wydajność
NikolaPolov
  • Rejestracja:około 8 lat
  • Ostatnio:prawie 7 lat
  • Lokalizacja:Warszawa
  • Postów:106
0

Cześć . Przypuśćmy że mam tablice z tysiącem obiektów . Przypuśćmy również że co pare sekund chciałbym usuwać wybrany przeze mnie obiekt . Metoda filer wydaje się oczywista ale filtrowanie tysiąca elementów żeby usunąć jeden wydaje się głupie . Czy znacie sposób jak to zrobić zachowując wydajność . Najlepiej jeżeli to nie tablica będzie miała za zadanie usunąć obiekt tylko aby obiektowi powiedzić aby usunął się z tablicy . PS wiem że to stworzy tablice rzadką ale co zrobić takie życie.


Nie byłbym sobą gdybym był kimś innym
Maciej Cąderek
Maciej Cąderek
tylko aby obiektowi powiedzić aby usunął się z tablicy ??
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
1

Może gdybyś miał pięćdziesiąt milionów obiektów, miałoby to jakieś znaczenie ;-)

premature optimization is the root of all evil


DE
  • Rejestracja:ponad 9 lat
  • Ostatnio:11 miesięcy
  • Postów:1788
1
  1. Pisz testy.
  2. Pisz kod bez optymalizacji, ale czytelny.
  3. Optymalizuj jeżeli zajdzie taka potrzeba, testy wykryją błędy.

Jeżeli masz 50 mln obiektów i często dodajesz/usuwasz, ale nie pobierasz elementów, to możesz spróbować zaimplementować LinkedList w js, ale nigdy nie próbowalem :)

edytowany 1x, ostatnio: Desu
Maciej Cąderek
Maciej Cąderek
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 3 lata
  • Lokalizacja:Warszawa
  • Postów:1264
2

Zapewne chcesz usuwać po jakimś id czy coś, wtedy lepiej użyć obiektu zamiast tablicy,
zamiast:

Kopiuj
const items = [
  { id: 1, name: 'foo' },
  { id: 2, name: 'bar' },
  { id: 3, name: 'baz' },
]

można zrobić tak:

Kopiuj
const items = {
  1: { id: 1, name: 'foo' },
  2: { id: 2, name: 'bar' },
  3: { id: 3, name: 'baz' },
}

Wtedy można użyć operatora delete (nie polecam, modyfikowanie kolekcji to zuo), lub użyć np lodashowej metody _.omit(object, key) (lub napisać taką funkcję samemu).

Dostęp poprzez klucz jest dużo szybszy i wygodniejszy niż wyszukiwanie w tablicy.

edytowany 3x, ostatnio: Maciej Cąderek
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:około godziny
  • Postów:8422
0

Przypuśćmy również że co pare sekund chciałbym usuwać wybrany przeze mnie obiekt .

Co parę sekund usuwanie jednego obiektu? Tu nie ma nic do optymalizacji xD Problemem by mogłoby być gdybyś musiał w ciągu sekundy usuwać np. 1000 obiektów. O ile faktycznie byłoby to problemem (takie rzeczy łatwo sprawdzić jakimś profilerem, np. tym wbudowanym w Chrome Dev Tools, które kawałki kodu ci naprawdę niszczą wydajność. Polecam sprawdzać, bo efekty często są nieintuicyjne (coś co miało być szybsze, jest wolniejsze), albo się okazuje, że wydajność zżera ci jakaś totalna pierdółka, o której nigdy byś nie pomyślał, że może zżerać ci wydajność.

modyfikowanie kolekcji to zuo),

Nie zawsze zło. Czasami to najlepsze wyjście, jeśli to uprości design albo jeśli inne podejście byłoby zbyt mało wydajne :) Wydaje mi się, że to nie same mutacje są złe, tylko raczej niespójność danych, która może z nich wynikać. Albo brak kontroli nad mutacjami (co innego jeśli masz kolekcję, którą każdy obiekt może zmieniać kiedy chce, a co innego jeśli masz coś w rodzaju Reduxa, gdzie każda mutacja jest zapisana w postaci akcji*, nad którą ma się większą kontrolę)

**pomijam już Redux niby jest niemutowalny - uważam, że jest to raczej szczegół implementacyjny. Myślę, że Reduxa można by napisać równie dobrze w mutowalny sposób. *

Metoda filer wydaje się oczywista ale filtrowanie tysiąca elementów żeby usunąć jeden wydaje się głupie .

masz jeszcze metodę splice https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Array/splice

poza tym możesz użyć obiektu (jak przedmówca napisał).

Możesz w ogóle nie kasować obiektów, tylko zaznaczać je jakoś jako usunięte (w tym przypadku to bez sensu, ale w pewnych przypadkach to fajny pattern, np. w grach gdzie zaznaczasz martwe postacie jako "dead" i dopiero potem usuwasz je grupowo w dogodnym czasie).

Możesz wykorzystywać ponownie obiekty, które zaznaczyłeś wcześniej jako usunięte (to się może przydać jeśli samo tworzenie obiektu/inicjalizacja jest kosztowna). Z tego co wiem, to React tak robi, że wykorzystuje ponownie pewne obiekty dla celów wydajności.

filtrowanie tysiąca elementów

Nie musisz filtrować tysiąca elementów. Możesz trzymać obiekty w jakimś drzewie i wyszukiwać obiekt przechodząc przez kolejne węzły drzewa. To też może być szybsze.

Tylko... że szczerze powiedziawszy to większość tych rzeczy to będzie overkill jeśli zmieniasz sobie coś tam co kilka sekund, ja bym na twoim miejscu zostawił to filter, ew. splice, czy użył sposobu mojego przedmówcy z obiektami.


Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.