What is boost::variant memory and performance cost?
Asked Answered
A

1

14

boost::variant seems a powerful container to manipulate a heterogeneous set of types. I am wondering its cost. In memory, I think it takes up the size of the largest type plus an integer representing which(). For apply_visitor(), I think its performance is very good, it can call directly the function other than lots of ifs. Are my points right?

Aneroidograph answered 2/10, 2014 at 2:42 Comment(2)
Boost is opensource. You could do a little research and browse source code. It looks like that you already know what to look for.Hitandrun
apply_visitor does "lots of ifs" under the hood (in fact it is more like a (big, metaprogrammed) switch on the kind (which()) of the variant. Obviously, that's simply the minimum work required.)Hohenlinden
S
13

You're almost right.

The size of boost::variant is is the max size of any element, rounded up as needed for the largest alignment, plus the size of some integer, and again rounded up.

Think about a variant of these types, assuming the tag is uint32_t:

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

An untagged union must have size 16, align 8; adding the 4-byte tag must go up to size 24 to keep align 8.

Or consider a variant of:

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

An untagged union of these must have size 6, align 2; adding the 4-byte tag forces you to size 12, align 4.

For calling, I expect it uses an array-of-functions lookup (that's how I implemented my own variant, which was necessary since boost's didn't support move constructors), since if chains don't perform well and switches are impossible.

Stillhunt answered 2/10, 2014 at 5:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.