如何快速复制std :: string内容?

时间:2014-01-22 19:12:16

标签: c++ string memcpy stdstring strncpy

我已阅读some related questions,但没有关于memcpystrncpy之间的速度比较。

您建议如何跟踪关键部分中的字符串内容?

  • 避免动态内存分配
  • 优雅的代码和可读/可理解的(少数代码行)
  • 快速处理(少量指令,防止分支错过)
  • 能够通过编译器进行优化(或已经使用优化指令的实现)

我在考虑功能:

  1. memcpy需要计算最小长度(请参阅coliru.stacked-crooked.com上的摘录)

    void copy (char dst[20], const std::string& src)
    {
        if (src.size() < sizeof(dst)) {
            memcpy (dst, src.c_str(), src.size()+1);
        } else {
            memcpy (dst, src.data(), sizeof(dst)-1);
            dst[sizeof(dst)-1] = 0;
        }
    }
    
  2. strncpy搜索终止空字节,不必要的填充所有最终字节(参见snippet

    void copy (const std::string src, char (*dst)[20])
    {
        strncpy (dst, src.c_str(), sizeof(dst)-1);
        dst[sizeof(dst)-1] = 0;
    }
    
  3. snprintf

  4. std::string::copy正如dyp的评论所建议的那样......

  5. std::copy同样dyp的评论建议......

  6. 还有其他想法吗?

  7. 可以执行基准测试,但它应该基于几个编译器/版本,不同的标志集和不同的硬件/操作系统。我希望根据您的反馈/背景/专业知识或数学知识得出答案......

    由于这是一个普遍的问题,搜索相同相关问题的人会欣赏一般性答案,而不是我自己特定的当前案例。

    为了您的信息,一个线程需要在文件中写入一些std::string,以便其他线程可以更改其内容。我不能改变这个其他线程,而这个其他线程非常繁忙。如果我没有锁定(mutex / spinlock)字符串副本,我有时会遇到一些问题。因此,我想快速复制这些std::string并在锁定部分之后写下它们。

2 个答案:

答案 0 :(得分:3)

首先,我不知道哪个版本更快。正如您可能知道的那样,它在很大程度上取决于您的编译器,系统,实现等。

如果您事先知道尺寸(您有std::stringsize()需要O(1)),那么可能更快使用{{1}因为它有更少的事情要做(只是复制,没有比较)。你可以这样写:

memcpy

但我不会接受任何人的话。正确的做法是测试你拥有的所有变化并决定你的特定场景(我对此一无所知)。


  

我的具体情况是在一个关键部分(旋转锁定)中快速存储一些void copy(char* buffer, std::size_t buffersize, const std::string& str) { std::size_t len = std::min(buffersize-1, str.size()); memcpy(buffer, &str[0], len); // using &str[0] instead of data() buffer[len] = '\0'; } 并在之后转储这些字符串。因此,我想阻止动态内存分配。

我不明白为什么不使用std::string。如果你想要防止分配,你可以std::string一些内存到你的字符串(与char数组相同的数量)。或者你可以对字符串进行const引用并在临界区使用它。不会进行任何分配。

答案 1 :(得分:0)

当你使用c_str()而不是data()时,你冒险std :: string创建一个临时副本以附加终止0.当你使用data()时,你不能使用stncpy。 / p>

不知道是否有很多实现真正执行该临时副本。为终结器浪费一个字节似乎并不是什么大问题。但是:

  • 在纯C ++代码中,你永远不需要c_str(),为什么要优化呢?
  • 这不仅浪费了一个字节,而且还需要时间来维护它
  • 某些实现避免为非常短的字符串分配额外的动态内存。 在那里,能够或多或少地存储一个字节。
  • 也许一个实现为子字符串操作进行了写时复制优化?