Overhead of std::optional<T>?
->
and *
ought to have zero overhead.
value
and value_or
ought to have the overhead of one branch: if(active)
Also, copy/move constructor, copy/move assignment, swap, emplace, operator==
, operator<
, and the destructor ought to also have the overhead of one branch.
However, one banch of overhead is so small it probably can't even be measured. Seriously, write pretty code, and don't worry about the performance here. Odds are making the code pretty will result in it running faster than if you tried to make it fast. Counter-intuitive, but do it anyway.
There are definitely cases where the overhead becomes noticible, for instance sorting a large number of optional
s. In these cases, there's four situations,
(A) all the optionals known to be empty ahead of time, in which case, why sort?
(B) Some optionals may or may not be active, in which case the overhead is required and there is no better way.
(C) All optionals are known to have values ahead of time and you don't need the sorted-data in place, in which case, use the zero overhead operators to make a copy of the data where the copy is using the raw type instead of optional
, and sort that.
(D) All optionals are known to have values ahead of time, but you need the sorted data in-place. In this case, optional
is adding unnecessary overhead, and the easiest way to work around it is to do step C, and then use the no-overhead operators to move the data back.
Besides the other answer, you should also consider that std::optional
requires additional memory.
Often it's not just an extra byte, but (at least for "small" types) a 2x space overhead due to padding .
Maybe RAM isn't a problem but that also means fewer values available in the cache.
A sentinel value, if specific knowledge allows to use it, could be a better choice (probably in the form of markable
to keep type safety).
An interesting reading is: Boost optional - Performance considerations