2013-05-07 16 views
32

Mam kod, w którym rutynowo wypełniam wektor od 0 do 5000 elementów. Wiem, że nigdy nie przekracza maksymalnej 5000. Zamiast inicjowania wektor wiele razy, chciałbym to zrobić tylko razC++ najszybszy sposób wyczyszczenia lub usunięcia wektora

vector<struct> myvector; 
myvector.reserve(5000); 

Jednak, aby ponownie napełnić wektor, muszę najpierw wyczyścić wektor bez zmiany jego pojemności. Zwykle nazywam się myvector.clear();

To jest operacja O (n). Czy jest coś prostego, co mogę zrobić, aby zwiększyć wydajność tego produktu lub czy jest on najlepszy z możliwych?

+2

Czy przypisywanie do istniejących elementów jest rozsądnym rozwiązaniem? –

+0

Nie, ponieważ mogę mieć 5000 elementów za pierwszym razem i 3500 następnym razem, a na końcu pozostanie 1500 starych elementów ... – user788171

+0

Czy "zniszczenie" elementów jest problemem? –

Odpowiedz

38

Jeśli twój struct ma nietrywialny destruktor, to musi on zostać wywołany dla wszystkich elementów wektora, bez względu na sposób jego opróżnienia. Jeśli twoja struktura ma tylko trywialny destruktor, kompilator lub standardowa implementacja biblioteki może zoptymalizować proces destrukcji i dać operację O (1).

+0

Istnieje różnica między * "kompilator prawdopodobnie zoptymalizuje ..." * i * "implementacja może optymalizuj koszty ... "* (jak powiedział @ DavidRodríguez-dribeas w swojej odpowiedzi). To ostatnie brzmi dla mnie bardziej rozsądnie! – Nawaz

+0

@Nawaz: Przypuszczam, że to prawda. Moją intencją było coś w rodzaju "większość kompilatorów wykonuje tę optymalizację, więc prawdopodobnie używasz jednego z tych kompilatorów", ale widzę, jak można to zinterpretować jako "czasami kompilator będzie, a czasami kompilator nie będzie optymalizował to, ale zazwyczaj będzie ". –

+0

Myślę, że nie zrozumiałeś mojego komentarza. Oświadczenie * "implementacja może zoptymalizować koszt z dala ..." * jest superkompletem, ponieważ zawiera również pomysł * "kompilator prawdopodobnie zoptymalizuje" *, oprócz możliwości "zoptymalizowanego" kodu biblioteki. Znaczy, nawet jeśli sam kompilator nie wykonuje optymalizacji, biblioteka mogłaby zostać napisana tak, by emitować kod 'O (1)', gdy 'typ_wartości' ma trywialny destruktor (co oznaczało także @ DavidRodríguez-dribeas, patrz jego komentarze). – Nawaz

10

Wszystko, co robisz, aby usunąć istniejące elementy z wektora, musi (potencjalnie) wywołać destruktor każdego zniszczonego elementu. Dlatego z punktu widzenia kontenera najlepsze, na co możesz liczyć, to złożoność liniowa.

Pozostaje tylko pytanie, jakie elementy przechowujesz w wektorze. Jeśli przechowujesz coś takiego jak int, które kompilator może/będzie wiedzieć z wyprzedzeniem, nie ma destruktora do wywołania, szanse są co najmniej całkiem dobre, że usunięcie zakończy się ciągłą złożonością.

Wątpię jednak, aby zmiana składni (np. clear() vs. resize() vs. erase(begin(), end())) spowoduje jakąkolwiek istotną różnicę. Składnia nie zmienia tego faktu, że (w przypadku braku wątkowania) wywołanie N destruktorów jest operacją O (N).

23

Koszt clear() zależy w dużej mierze od tego, jakie przechowywane są obiekty, aw szczególności od tego, czy mają one trywialny destruktor. Jeśli typ nie ma trywialnego destruktora, to wywołanie musi zniszczyć wszystkie przechowywane obiekty i jest to faktycznie operacja O (n), ale tak naprawdę nie można zrobić nic lepszego.

Teraz, jeśli przechowywane elementy mają trywialne destruktory, wówczas implementacja może zoptymalizować koszt, a clear() staje się tanią operacją O (1) (wystarczy zresetować rozmiar - wskaźnik end).

Pamiętaj, że aby zrozumieć asymptotyczną złożoność, musisz wiedzieć, o czym mówi. W przypadku clear() reprezentuje liczbę wywoływanych destruktorów, ale jeśli koszt (ukryty) wynosi 0, operacja to operacja "no-op".

+0

Czy możesz wyjaśnić, co należy rozumieć przez trywialnego destruktora? Nie znam tej terminologii. – user788171

+8

Myślę, że w tym kontekście "trywialny destruktor" jest tym samym, co 'no destructor'. –

+4

@ user788171: Możesz przeczytać [Co to są Aggregates i POD i jak/dlaczego są one specjalne?] (Http://stackoverflow.com/a/7189821/2070725), aby zrozumieć, co to wszystko "trywialne" rzeczy to około (przewiń w dół, by dojść do "trywialnej" części). – syam

Powiązane problemy