【问题标题】:Fastest Way to Copy Buffer or C-String into a std::string将缓冲区或 C-String 复制到 std::string 的最快方法
【发布时间】:2014-11-28 08:37:09
【问题描述】:

假设我有char buffer[64]uint32_t length,而buffer 可能会或可能不会以null 终止。如果它以空值终止,则缓冲区的其余部分将被空值填充。 length 变量保存缓冲区的长度。

我想将它复制到一个std::string 中,在字符串对象的末尾没有多余的空值。

最初,我尝试过:

std::string s(buffer, length);

当缓冲区最后被空值填充时复制额外的空值。

我能想到:

char buffer2[128];
strncpy(buffer2, buffer, 128);
const std::sring s(buffer2);

但这有点浪费,因为它复制了两次。

我想知道是否有更快的方法。我知道我需要进行基准测试以准确判断哪种方式更快......但我想看看其他一些解决方案,然后进行基准测试......

提前致谢。

【问题讨论】:

    标签: linux gcc c++11 stdstring


    【解决方案1】:
    1. 如果可以,我只需在缓冲区末尾添加 '\0' 并 然后使用 string 构造函数的 c 字符串版本。

    2. 如果不能,您需要确定您的文件夹中是否有 '\0' 缓冲区,当你在它的时候,你不妨数数 在'\0' 之前遇到的字符。然后你可以使用它 使用string 构造函数的(buffer,length) 形式计数:

      #include <string.h>
      //...   
      std::string s(buffer, strnlen(buffer, length));
      
    3. 如果你不能做 1. 并且不想迭代 buffer 两次(一次确定长度,一次在字符串构造函数中),你可以这样做:

      char last_char = buffer[length-1];
      buffer[length-1] = '\0';
      std::string s(buffer);  //the c-string form since we're sure there's a '\0' in the buffer now
      if(last_char!='\0' && s.length()==(length-1)) {
      //With good buffer sizes, this might not need to cause reallocation of the strings internal buffer
           s.push_back(last_char); 
      }
      

      我将基准测试留给您。无论如何,构造函数的 c 字符串版本可能会在内部使用类似 strlen 的东西来避免重新分配,因此使用 c-string 版本的 string 构造函数可能不会有太多好处。

    【讨论】:

    • 很遗憾,我无法在末尾添加 '\0'。您的替代解决方案非常出色。谢谢!
    【解决方案2】:

    您可以使用所有规范的方式来做到这一点。

    更快的方法肯定是自己实现 smartpointer (或使用任何已经完成的作为std::shared_ptr )。

    每个智能指针 (sp) 指向数组的第一个字符并包含。

    每次您执行 array.copy 时,您都不会执行真正的复制,而是只需添加一个引用来执行该数组。

    所以,“复制”需要 O(1) 而不是 O(N)

    【讨论】:

      猜你喜欢
      • 2015-02-07
      • 1970-01-01
      • 1970-01-01
      • 2013-06-16
      • 1970-01-01
      • 2016-08-29
      • 2017-01-05
      • 2015-09-06
      • 1970-01-01
      相关资源
      最近更新 更多