【问题标题】:Should std::list::size have constant complexity in C++11?std::list::size 在 C++11 中是否应该具有恒定的复杂性?
【发布时间】:2013-10-09 20:34:13
【问题描述】:

我正在使用 gcc 4.8.1,经过数小时调试一个可怕的神秘性能问题后,我发现 std::list::size 实际上是作为对 std::distance 的调用实现的。

/**  Returns the number of elements in the %list.  */
      size_type
      size() const _GLIBCXX_NOEXCEPT
      { return std::distance(begin(), end()); }

这让我很惊讶,因为参考资料说complexity of std::list::size should be constantstd::distance 的复杂性对于std::list::iterator 是线性的。

我真的很困惑,因为我认为 gcc 对 C++11 特性有很好的支持,我看不出他们为什么不实现这个。

这是引用中的错误还是 gcc 中的错误?

在后一种情况下:

有什么理由让这样一个基本的 C++11 特性消失了这么久?

是否有第三种可能性,例如:

我可以有 gcc 4.8.1 但标准库的一些旧版本吗?

【问题讨论】:

  • 在 C++03 中是 O(n),在 C++11 中已经更改,现在是 O(1)。似乎 GCC 还没有更新这个位。不好。
  • GCC 有许多违反 C++11 的标准。 liststring 浮现在脑海中;在遵守旧代码和破坏旧代码之间做出艰难的选择。
  • @MartinDrozdik:在算法上似乎存在问题。通常你需要empty(),但很少需要size()。如果您的算法确实需要一个列表(而不是向量),您通常只需查询列表中是否有 something 并将其弹出。
  • @MartinDrozdik:vector 在使用push_back 时具有摊销复杂性,因此您应该能够让它以相对较低的成本增长(取决于在其中移动对象的成本,当然)。
  • gcc-5 默认情况下具有 C++11 兼容 std::liststd::string。这是其他人指出的 ABI 重大更改。有一种机制涉及允许切换的内联命名空间。努力确保旧的库不会损坏。我相信这将在发布时更详细地说明,应该是 RSN。

标签: c++ gcc c++11 c++-standard-library


【解决方案1】:

这并不完全是一个错误,您可以在这里阅读:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49561

这更像是与旧版本 gcc 的兼容性。 看起来他们真的不想添加额外的“数据成员”。

引用:

此补丁使 c++98 和 c++11 代码不兼容,并导致 发行版的严重问题。

patch 是他们为 gcc 4.7 实施的修复程序(其中是 O(1))。

另一个引用:

已决定保持 ABI 兼容性更为重要 对于当前版本

【讨论】:

  • 我想知道为什么O(1) 会破坏旧代码?不管是O(n)还是O(1),客户端代码list.size()都是一样的。
  • @Nawaz:因为将其实现为 O(1) 需要在 list 类中添加一个“大小”变量,从而破坏了二进制兼容性。
  • @Nawaz:他们非常努力。为什么你认为string 已经坏了很多年了? __vstring 是正确的,但由于担心破坏向后兼容性,它没有被设为默认字符串类。
  • @MSalters 有什么方法真的不会破坏 ABI?请记住,问题在于存在混合 C++98 和 C++11 代码的代码;就像在模块之间传递列表一样,在 C++11 列表上使用 C++98 列表成员函数,反之亦然,并且可能将使用 gcc 4.x 编译的 C++98 二进制文件与使用 gcc 4 编译的 C++11 二进制文件混合。是的。
  • @bames53:这通常是可能的,但一般情况下,调用改变大小的 C++98 方法几乎肯定会破坏 O(1) 大小。它现在会知道缓存的大小成员,并且无法更新它。这确实意味着 C++11 实现必须检测过时的大小值,但它可以为此使用任何类型的脏实现黑客。例如。将指针的最低位设置为头节点,假设节点指针至少 2 字节对齐。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
  • 2014-11-28
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多