1

我已经阅读了一些 相关的 问题memcpy,但没有关于和之间的速度比较strncpy

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

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

我在考虑函数:

  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搜索终止空字节和不必要的填充所有最终字节(见代码片段

    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. 还有其他想法吗?

可以执行基准测试,但它应该基于多个编译器/版本、不同的标志集和不同的硬件/操作系统。我更喜欢基于您的反馈/背景/专业知识或数学知识的答案......

由于这是一个一般性问题,搜索相同相关问题的人会喜欢一般性答案,而不是我自己当前的具体案例。

供您参考,一个线程需要在文件中写入一些std::string内容,以便另一个线程可以更改它们的内容。我无法更改此其他线程,并且此其他线程非常忙。如果我不锁定(互斥/自旋锁)字符串副本,我有时会遇到一些问题。因此,我想快速复制这些std::string并将它们写在锁定部分之后。

4

2 回答 2

3

首先,我不知道哪个版本更快。正如您可能知道的那样,它高度依赖于您的编译器、系统、实现等。

如果您事先知道大小(您有一个std::stringand ),使用它size()可能更快,因为它要做的事情更少(只是副本,没有比较)。你可以这样写:O(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. 如果您想防止分配,您可以reserve()为您的字符串分配一些内存(与您在 char 数组上的内存量相同)。或者您可以对字符串进行 const 引用并在关键部分使用它。不会进行任何分配。

于 2014-01-22T19:55:43.537 回答
0

当您使用 c_str() 而不是 data() 时,您可能会冒 std::string 创建临时副本以附加终止 0 的风险。而当您使用 data() 时,您不能使用 stncpy。

不知道是否有许多实现实际执行该临时副本。为终结者浪费一个字节似乎没什么大不了的。但:

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