2014-04-10 24 views
5

Czytałem TC++ PL o komponencie raw_storage_iterator. Korzystając z tego komponentu uzyskujemy korzyści związane z wydajnością, ponieważ unika się przypisania (droższego) i wykorzystuje konstrukcję kopii. Wydawało mi się, że powinien on być użyty w sekwencji/pojemniku, w którym moglibyśmy mieć znaczną liczbę elementów, a zatem liczba wywołań może mieć duży wpływ.Co to jest komponent raw_storage_iterator używa/zalety w C++

Teoretycznie jest to jasne i wydawało mi się, że ten komponent jest przydatny w przypadku klas typu kontenera. Chciałbym jednak zrozumieć, gdzie powinniśmy użyć tego komponentu (z praktycznymi przykładami) w szczegółach bitowych, aby uzyskać korzyści z wydajności?

+0

inb4 "cplusplus.com jest do bani, nie waż się linkować do niego"; Mówi się, że jest używany, więc możesz użyć niezainicjowanej pamięci jako miejsca docelowego dla algorytmów. Wydajność nie powinna być lepsza niż w przypadku zarezerwowanego wektora z iteratorem wstecznym. Jeśli nie piszesz kodu bardzo niskiego poziomu, nie potrzebujesz tego iteratora. – DanielKO

+0

@ Danielok zarezerwowany wektor z iteratorem wstecznym musi sprawdzać rozmiar w każdej wstawce. Kompilator uznający, że sprawdzanie rozmiaru nie jest potrzebne, jest stosunkowo mało prawdopodobny. Dostaniesz dobre przewidywanie rozgałęzień na czeku, ale nadal będzie ono mniejsze niż pisanie "raw_storage_iterator". – Yakk

Odpowiedz

3

Po numerem cppreference znajduje się przykładowy kod.

Można przydzielić wyrównane bloki niezainicjowanej pamięci za pomocą wielu mechanizmów. Cppreferences używa std::get_temporary_buffer<T> do przydzielenia takiego bufora.

Następnie można wprowadzić wskaźnik do tych elementów. Typ wskaźnika jest nieco mylący, ponieważ nie jest wskaźnikiem do zmiennej, ale raczej do bloku pamięci, który jest odpowiedni do skonstruowania modelu T.

Można wpisać T* i przekazać mu dane wyjściowe. Następnie możesz przekazać ten iterator do algorytmu, który oczekuje konwencjonalnego iteratora wyjścia i wszystko idzie gładko.

Jeśli próbowałeś to zrobić bez raw_storage_iterator, przypisałbyś nieskompresowanemu T, który jest niezdefiniowanym zachowaniem. Alternatywnie możesz skonstruować T przed wysłaniem do nich - ale jest to marnotrawstwem, ponieważ konstruuje obiekt dwukrotnie.

Podstawową ideą jest umożliwienie użycia niezainicjowanych buforów wyjściowych z niemal doskonałą wydajnością w standardowych algorytmach. To nie jest coś, co powinieneś używać poza jakąś poważną mikrooptymalizacją kodu.

+0

Czy nie byłoby to dobre miejsce do zastosowania nowego miejsca docelowego zamiast tego? Spowoduje to, że skonstruowany obiekt przejdzie w zarezerwowanym miejscu na raz. To nadal wymaga od programisty zdobycia wystarczającej ilości miejsca, ale wydaje się, że może to być lepsza wydajność i bezpieczeństwo. – Paul

+0

@paul ten iterator używa miejsca docelowego 'nowy', po prostu robi to po przypisaniu do. Iterator surowej pamięci masowej pozwala ci to zrobić jako wyjście do jakiegoś algorytmu z 'std' - niektóre z nich możesz nie chcieć ręcznie odtwarzać. – Yakk