boost::optional 的效率是什么?

5

我有以下内容:

class Obj;
typedef std::map<string, string> StrMap;
std::map<std::string, std::pair<Obj, StrMap> > complexMap;

问题在于,对于复杂映射中的某些条目,StrMap将为空,我根本不会使用它,因此为了提高效率,我考虑使用boost :: optional。我的问题是boost :: optional的效率如何,我担心通过支付其价格最终将一无所获。


4
你是否对代码进行了分析,并确定由于创建空映射而导致性能瓶颈? - Luc Touraille
1
@LucTouraille,不,我只是希望获得最高的性能。 - Subway
1
你在考虑什么替代方案?寻找“最高性能”的方法是对不同的解决方案进行分析,然后选择性能最高的方案。 - juanchopanza
3
好的,但你想要与之进行比较的替代方案是什么? - juanchopanza
考虑可选项的实现方式,它通常具有一些内部存储(以允许它保存映射对象 - 就像您在上面的代码中所做的那样),唯一的区别是它不会在该存储中构造映射 - 这留给以后再做。但是必须构造可选对象。因此,现在你不仅要构造一个映射,而且在不使用映射的情况下,还要构造一个更大的可选对象,在使用映射时,你也必须构造映射。看起来你为了很少的好处做了更多的事情。 - Nim
显示剩余2条评论
3个回答

6
请注意格式:

optional看作是一个可以容纳0或1个值的容器。你的map已经是一个可以容纳0到N个元素的容器了。因此,一个可选的map就是一个容器中的容器,可以容纳0到N个元素。但实际上,并没有什么好处。

一个空map的开销非常小。从内部来看,map实际上是由map节点构建的,而一个空map就没有任何节点。(它不能有,因为每个节点都有一个值,而一个空map无法创建默认值)


2
如果您正在进行“稀疏”计算,可以采取两种方法:
1. 保留一个大的包含许多不存在结果的complexMap,并使用boost::optional封装每个元素的稀疏性。
2. 创建一个额外的间接层(例如unordered_map),其中包含指向complexmMap中现有元素的指针。这将在每个地图的基础上封装稀疏性。
作为程序员,方案1会更加方便,需要付出一些空间开销但思考较少。方案2几乎完全节省空间,使complexMap尽可能小,但需要更多的编程工作。
请选择对您更可接受的方案(提示:如果您在complexMap中进行千兆字节级别的计算,则额外的间接层可能会有所回报,否则我不会费心)。
除了空间开销之外,boost::optional几乎没有其他成本,因为它不需要默认构造函数或动态内存分配。

2
将评论转换成答案...
考虑可选项的实现方式,它通常具有一些内部存储(允许其保持地图对象 - 正如您在上面的代码中所做的那样),唯一的区别是它不会在该存储中构建地图 - 这留给以后处理。但必须构造可选对象。因此,现在你不仅要构造一个地图,而且还要在不使用地图的情况下构造更大的可选对象,在使用地图时也必须构造地图。看起来你为了很小的好处而做了更多的事情。
有些情况下,可选确实有意义(例如返回值,其中您想指示无效状态,或者您有一个非常昂贵的构造函数,它对复杂成员进行大量初始化的情况),但对于具有微不足道构造函数的对象,可选真的不值得代码混乱。
免责声明:但与所有性能相关的问题一样,请进行性能分析,然后再进行分析...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接