【问题标题】:C++ string class efficiencyC++ 字符串类效率
【发布时间】:2018-05-17 18:10:23
【问题描述】:

我有一个多年前写的旧字符串类(在标准库如此标准之前)。它工作正常,但我想我应该在我的最新项目中进入 21 世纪。我想知道标准库字符串类的效率如何。例如,如果我将一个字符串传递给一个函数或简单地将它分配给另一个字符串,它会复制数据,还是简单地复制一个指向数据的指针。

在我的旧课程中,我对数据进行了引用计数,并只是复制了指针。如果我做了一些修改字符串的事情,我会检查它的引用是否为 1。如果它是 1,我可以使用相同的字符串数据区域,假设字符串没有增长到超过它的原始大小。如果它大于 1,我会在修改之前复制字符串数据。

标准库类是否做类似的事情(或希望更好),还是在每次传递字符串时复制数据。我想这可能取决于实现。我目前正在为 Windows 开发,但我可能稍后会移植它。谢谢

【问题讨论】:

  • std::string 在大多数情况下可能会因为小字符串优化而超过您的性能。移动支持等。但你应该分析并找出答案。
  • @Jabberwock 不同之处在于我可以通过“值”将 COW 字符串传递给新线程,并认为我是线程安全的。使用std::string,您是线程安全的,因为您确实得到了一份副本。这允许您执行诸如在 C++17 中拥有非const data() 成员之类的事情,因为如果您使用值语义,您可以确保缓冲区不应跨线程共享。
  • 如果你让你的 COW 字符串类线程安全,那么当你在非线程的情况下使用它时,你付出了高性能的代价。
  • @Jabberwock 警告词,如果您在线程环境中使用 COW 字符串,请务必非常小心。您可能会导致未定义的行为。
  • 好吧,对于std::string,您希望尽可能移动而不是复制。使用 COW 字符串,您总是添加引用。

标签: c++ string performance


【解决方案1】:

事实证明,在大多数情况下,小字符串优化比 COW 更有效。不过,这并不是一定会赢的。它在很大程度上取决于它的使用方式。但是我认为您始终可以使用std::shared_ptr<std::string> 来实现您的 COW 类并为自己节省大量手动内存管理的废话。

底线是,std::string可能更好,但这里的细节可以改变它。尝试一下,但要小心。

【讨论】:

    【解决方案2】:

    std::string 的界面臃肿,你会得到 copy-on-potential-write,效率要低得多。

    例如在char& c = s[i]; c = 'a'; 中,当s 恰好被共享时,如果需要创建单独的COW 项目,则不允许c 的分配抛出bad_alloc。所以我们必须在每次对s[i] 的非常量调用中取消共享字符串,以防万一。

    实际上,这限制了共享潜力很多,同时还向许多字符串成员函数添加了大量if (shared) unshare(); 代码。在多线程代码中,这是一个真正的性能杀手,因为unshare() 在取消共享时必须锁定对象。

    【讨论】:

      猜你喜欢
      • 2020-10-06
      • 1970-01-01
      • 2020-01-21
      • 2015-06-16
      • 2011-10-21
      • 2017-08-13
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多