std::可选的开销<T>?

问题描述 投票:0回答:2

现在 std::experimental::Optional 已被接受(或即将被接受),我想知道当通过以下运算符获取内部值时生成的程序集的开销和后果是多少:

->
*
value
value_or

与没有

std::optional
的情况相比。这对于计算密集型程序尤其重要。

例如,与

std::vector<std::experimental::optional<double>>
相比,
std::vector<double>
上的操作开销的数量级是多少?

performance g++ c++14 overhead stdoptional
2个回答
18
投票

->
*
的开销应该为零。

value
value_or
应该有一个分支的开销:
if(active)

此外,复制/移动构造函数、复制/移动赋值、交换、emplace、

operator==
operator<
,以及析构函数也应该有一个分支的开销。

然而,一堆开销是如此之小,甚至可能无法测量。 说真的,写漂亮的代码,不要担心这里的性能。 很可能使代码变得漂亮会导致它运行得比你试图使其更快的速度更快。 违反直觉,但无论如何都要这样做。

在某些情况下,开销会变得明显,例如对大量

optional
进行排序。 在这些情况下,有四种情况:

  1. 所有提前已知为空的选项,在这种情况下,为什么要排序?
  2. 某些选项可能会或可能不会处于活动状态,在这种情况下,开销是必需的,并且没有更好的方法。
  3. 已知所有选项都提前具有值,并且您不需要就位排序数据,在这种情况下,请使用零开销运算符来复制数据,其中副本使用原始类型而不是
    optional
    ,然后排序 that
  4. 已知所有选项都提前具有值,但您需要就地排序数据。 在这种情况下,
    optional
    会增加不必要的开销,解决该问题的最简单方法是执行步骤 C,然后使用无开销运算符将数据移回

17
投票
除了其他答案之外,您还应该考虑

std::optional

需要额外的内存。

通常它不仅仅是一个额外的字节,而是(至少对于“小”类型)由于填充而产生的

2x 空间开销。

也许 RAM 不是问题,但这也意味着缓存中可用的值更少。

哨兵值,如果特定知识允许使用它,可能是更好的选择(可能以

markable

 的形式来保持类型安全)。

有趣的阅读是:

Boost 可选 - 性能考虑因素

© www.soinside.com 2019 - 2024. All rights reserved.