【问题标题】:std::string as map key and efficiency of map.find()std::string 作为映射键和 map.find() 的效率
【发布时间】:2014-04-25 01:19:04
【问题描述】:

我有一个std::map<std::string,foo> 并且需要经常使用find() 元素,而不是std::string,我有一个const char*。但是,map.find("key_value") 不起作用,我需要一个 std::string。所以,我需要map.find(std::string{"key_value"}),但这每次都会创建一个临时的std::string(及其分配和取消分配),这可能会导致效率低下。这个推理正确吗?如果是,我该如何改善这种情况?

我正在考虑使用const char* 周围的包装器作为地图的关键,它具有自己的比较功能并且可以廉价地包装在任何const char* 周围,无需分配。这是一个好主意吗? (请注意,我的映射值不可复制,只能移动)。

【问题讨论】:

  • 您测量过性能影响吗?这是性能下降的主要原因吗?
  • 相关性 - 你考虑过std::unordered_map吗?您的 find() 调用将是 O(1)。
  • 太糟糕了std::map 没有find 的模板版本,它接受任何与密钥类型相当的内容。

标签: c++ string map


【解决方案1】:

您可以通过使用以 0 结尾的字符串和地图的自定义比较器来避免临时变量。
不过,使用 unordered_map 可能会产生更好的索引性能。

正如您所想的那样,另一种选择(更好)是使用包装器。
实际上已经有 std::reference_wrapper 用于该任务。

不过,优化的第一条规则:不要这样做。
第二条规则:不要不要这样做。
第三条规则(仅适用于专家):经过衡量和仔细考虑,无论如何你都可以这样做。

唯一的缺点是:您必须手动管理字符串的生命周期。

如果您还是要走这条路,并且在释放所有字符串之前不释放任何字符串,请考虑使用您自己的自定义分配器。

【讨论】:

  • 我知道我可以,我自己在问题中这么说。但这是个好主意吗?
  • @Walter:几乎每次,没有。尽管如此,您仍然可以拥有一个值得的案例。
  • 这令人困惑。根据thismap.find() 不允许使用const char* 参数,但是 gcc 和 clang 都可以正常编译并且可以正常工作?!?!
  • 涉及到std::string 的隐式转换。让他们给你重载:使用不合适的参数调用并解码错误消息。
  • 只是为了让您了解最新情况。我实际上是这样做的:在const char* 周围定义一个包装器,重载所有比较运算符和类型转换,并使用自定义分配器(分配许多char 的块)。工作正常。或者,可以简单地为std::string 提供一个自定义分配器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
  • 1970-01-01
  • 2016-07-28
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多