5

我有以下内容:

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

问题是对于 complexMap 中的某些条目,StrMap 将为空,我根本不会使用它,因此为了提高效率,我正在考虑使用 boost::optional。我的问题是 boost::optional 的效率是多少,我担心付出它的代价我最终将一无所获。

4

3 回答 3

5

可以将optional其视为可以容纳 0 或 1 值的容器。您的地图已经是一个可以容纳 0 到 N 个元素的容器。因此,可选映射是一个容器中的容器,可以容纳 0 到 N 个元素。真的,这里没有任何好处。

空地图的开销非常小。地图实际上是在内部从地图节点构建的,而空地图没有任何节点。(它不能,因为每个节点都有一个值,并且空映射无法创建默认值)

于 2013-06-25T09:06:20.983 回答
2

如果您正在进行“稀疏”计算,您可以做两件事:

  1. 用 .保留一个complexMap包含大量不存在结果的大数据boost::optional。这封装了基于每个元素的稀疏性。
  2. 创建一个额外的间接层(unordered_map例如),其中包含指向complexmMap. 这在每个地图的基础上封装了稀疏性。

备选方案 1 对您作为程序员来说会更方便,尽管需要很少的空间开销。备选方案 2 将几乎完全节省空间并保持complexMap尽可能小,但需要更多的预先编程工作。

选择您更容易接受的替代方案(提示:如果您在 中进行千兆字节级别的计算complexMap,那么额外的间接级别可能会得到回报,否则我不会打扰)。

除了空间开销之外,几乎没有其他成本boost::optional,因为它不需要默认构造函数或动态内存分配。

于 2013-06-25T08:20:34.747 回答
2

将评论移至答案...

想想如何实现可选的,它通常有一些内部存储(允许它保存地图对象 - 就像你在上面的代码中那样),唯一的区别是它不在那个存储中构造地图- 这个留到以后。但是必须构造可选对象。所以现在不只是构造一个地图,而是在你不使用地图的情况下构造一个更大的可选对象,当你使用地图时,你也必须构造它。似乎你在做更多的事情却没有什么好处。

在某些情况下optional确实有意义(例如返回值,例如,您想指示无效状态,或者您有一个非常昂贵的构造函数,它对复杂成员进行了大量初始化),对于具有琐碎构造函数的对象,可选真的是不值得代码混乱。

免责声明:但与所有与性能相关的问题一样,配置文件,配置文件,然后再次配置文件......

于 2013-06-25T08:25:20.213 回答