2014-10-02 17 views
9

boost :: variant to potężny kontener do manipulowania heterogenicznym zbiorem typów. Zastanawiam się nad jego kosztami. W pamięci, myślę, że zajmuje ona rozmiar największego typu plus liczbę całkowitą reprezentującą która(). Dla apply_visitor(), myślę, że jego wydajność jest bardzo dobra, może wywołać bezpośrednio funkcję inną niż wiele ifs. Czy moje punkty są prawidłowe?Co to jest boost :: variant memory and performance cost?

+0

Zwiększenie jest źródłem otwartym. Możesz zrobić trochę badań i przeglądać kod źródłowy. Wygląda na to, że już wiesz, czego szukać. – Drop

+2

'apply_visitor' robi" wiele ifs "pod maską (w rzeczywistości jest bardziej jak (duży, metaprogramowany) przełącznik tego rodzaju (' który() ') wariantu Oczywiście jest to po prostu minimalna wymagana praca.) – sehe

Odpowiedz

11

Masz prawie rację.

Wielkość boost::variant jest to maksymalny rozmiar jakichkolwiek elementu zaokrągla się w razie potrzeby do największego wyrównania plus wielkości pewnej liczby całkowitej i ponownie zaokrąglone.

Pomyśl o odmianie tych typów, przy założeniu, że znacznik jest uint32_t:

struct foo { uint32_t value[3]; }; // size 12, align 4 
struct bar { uint64_t v2; }; // size 8, align 8 

nieotagowanego Unia musi mieć rozmiar 16, wyrównać 8; dodając tag 4-bajtowy musi iść do rozmiaru 24, aby zachować Wyrównaj 8.

Albo rozważyć wariant:

struct foo { uint8_t value[5]; }; // size 5, align 1 
struct bar { uint16_t v2; }; // size 2, align 2 

nieotagowanego unia z nich musi mieć rozmiar 6, wyrównać 2; dodanie 4-bajtowego tagu zmusza cię do rozmiaru 12, wyrównanie 4.

W przypadku wywoływania, oczekuję, że użyje wyszukiwania tablic funkcji (w ten sposób zaimplementowałem własny wariant, który był konieczny, ponieważ boosty nie konstruktory ruchu wsparcia), ponieważ jeśli łańcuchy nie działają dobrze, a przełączniki są niemożliwe.