Podczas realizowania pewnego zadania musiałem na krótki czas lokować pamięć dla dużych obiektów. Okazało się, że, w tym konkretnym wypadku (liczył się czas wykonania, a pamięci było w opór) bardziej opłacało się przenosić obiekty (z użyciem std::move) do wektora zaalokowanego na ileś tam tysięcy obiektów i kiedy zadanie zostało zrealizowane, zwalniać każdy obiekt po kolei.
To chyba skrót myślowy, bo std::move
nic nie przenosi. Rzutuje obiekt na rvalue ref, dzięki czemu można w odpowiednim kontekście wywołać move constructor albo move operator, które z kolei mogą wywołać move constructor i move operator dla pól klasy. W skrócie - efektem powinno być ponowne użycie tej samej dynamicznie zaalokowanej pamięci, zamiast alokacji nowej.
Nie wiem jak wyglądały Twoje dane, ale jeżeli wszytko było polem klasy, to kosztem były małe alokacje. Jeżeli biblioteka standardowa nie posiadała odpowiedniej ilości pamięci od systemu, to co chwila musiała prosić o nowe strony.
(Chyba, że mówisz o move z algorithms, ale efekt będzie taki sam ... )
Wiem, że samo zadanie wykonuje się szybciej niż niszczenie obiektu po użyciu jednak rozwiązanie nie jest jeszcze całkiem przetestowane.
A co rozumiesz przez niszczenie obiektu? Wywołanie destruktora? Twoje "obiekty" robiły coś więcej poza zwalnianiem buforów w destruktorze? W jaki sposób to jest wolne? Oddajesz pamięć do alokatora biblioteki standardowej, a ten sobie porządkuje swoje odcinki pamięci.
Zastanawia mnie czy możliwa byłaby implementacja takiego GC, który zanim usunie obiekty, łączy je w większe obszary i zwalnia je kiedy przekroczą określoną wielkość. Czy teoretycznie dałoby to jakiś zysk w prędkości wykonania? Czy tak działają GB w Javie lub C#?
Obiekty czy pamięć? Pamięć dostajesz od biblioteki standardowej (no chyba, że alokujesz strony manualnie) i ta posiada odpowiednie mechanizm zwalniania i scalania pamięci. Natomiast niszczenie obiektu, to tylko wywołanie funkcji sprzątającej.
Trochę mi się to kojarzy z placement new
(a od c++20 także, std::construct_at
), które pozwala stworzyć obiekt na wskazanym miejscu w pamięci, ale nic o tym nie wspominasz.
Nawet w C się da. Pracuję nad duża bazą kodu w C i mamy predefiniowane bufory dla obiektów o danym rozmiarze per wątek, a także funkcje, które periodycznie oraz partiami zamiatają niektóre bufory, których czas życia nie do końca jest znany, szukając starych do usunięcia. Ale tylko dlatego, że czas życia jest związany z timerem.
Technik optymalizacji nie brakuje i już parę padło, ale najpierw trzeba poznać istotę problemu. Profiler Twoim najlepszy przyjacielem ; ).