A skąd wiesz że ta funkcja jest powolna, jeżeli nie wiesz co w tej funkcji jest powolne? Wiesz, Visual ma profiler który pokaże gdzie procesor spędził ile procent czasu.
Jak się ma rozmiar
_natures do rozmiaru pozostałych kontenerów?
for( auto & nature: _natures ) {
auto it = std::find( natures.begin(), natures.end(), nature ); if( it != natures.end() )
natures.erase( it );
Niech
n to rozmiar
_natures i
N to rozmiar
natures. Ten kod ma złożoność
O(nN). Dla każdego z
n elementów dotykasz każdy z
N elementów. Do pewnego punktu wyszukiwaniem, a dalej usuwaniem. Nawet jeżeli zoptymalizujesz wyszukiwanie, masz tu co najmniej pesymistyczne
O(n2) w usuwaniu, więc dla dużego
n będzie wolno. Dlatego ja bym tu odwrócił pętle i konstruował nowy kontener
natures/
gameObjects z samych elementów które mają zostać, wtedy wyszukiwanie robimy w małym kontenerze
_natures, który na potrzeby tego algorytmu można skopiować do kontenera zoptymalizowanego pod kątem wyszukiwania, np
std::set<>, albo
std::unordered_set<>.
for( int i = gameObjects.size() - 1; i >= 0; i-- )
if( gameObjects[ i ]->exist == false )
gameObjects.erase( gameObjects.begin() + i );
Jak możesz to oczywiście najszybciej jest wewnętrznie oznaczyć obiekty, zamiast robić wyszukiwanie. Natomiast wyobraź sobie
N = 100 * n i usuwasz pierwsze
n elementów. Złożoność to wtedy
O(n*(N-n)) więc dalej kwadratowa w pesymistycznym przypadku. Jeśli tylko możesz, nie usuwaj w pętli obiektów ze środka kontenera bo złożoność będzie słaba. Użyj
std::remove_if() i jednego wywołania
erase() by usunąć zakres elementów, co da czas liniowy w każdym ułożeniu elementów.
std::remove_if() nadpisuje usuwane elementy następnym nieusuniętym elementem, co zostawia wolne miejsce na końcu kontenera, które możesz usunąć w czasie stałym.