你会建议这种方法来复制字符串吗?

时间:2010-11-15 12:08:41

标签: c++ performance string reference copy

为了获得更高的性能,你是否建议在复制字符串时使用下面的方法,特别是当字符串中有很多字符时,大于12?

 unsigned char one[12]={1,2,3,4,5,6,7,8,9,10,11,12};
 unsigned char two[12];
 unsigned int (& three)[3]=reinterpret_cast<unsigned int (&)[3]>(one);
 unsigned int (& four)[3]=reinterpret_cast<unsigned int (&)[3]>(two);
 for (unsigned int i=0;i<3;i++)
  four[i]=three[i];

7 个答案:

答案 0 :(得分:5)

不,(几乎)永远不会。使用std::strcpy(虽然不是在这种情况下,因为您的“字符串”不是零终止),或std::copystd::string复制构造函数。

这些方法优化为您完成工作。如果您的代码(或类似的东西)碰巧比通过字符复制的天真字符更快,请放心strcpy将在下面使用它。事实上, 会发生什么(取决于架构)。

不要试图超越现代编译器和框架,除非你是领域专家(通常不是那时)。

答案 1 :(得分:3)

也许memcpy / std::copy?那些不会被优化吗?

答案 2 :(得分:2)

我相信大多数今天的编译器已经优化了字符串副本。无论如何你应该对此进行基准测试,并与memcpy进行比较,但我认为优化不值得失去可读性。

答案 3 :(得分:1)

我同意其他回复。通常,尝试优化块复制的次数往往比目标操作系统提供的速度慢。例如,memcpy(),memmove()等通常会实现此算法的一些变体:使用GP寄存器复制字/半字/字节,直到达到16字节对齐,然后使用SSE一次复制4个字(这是一次16个字符,提供sizeof(char)== 1)。

然后,你还可以测试你的实现与memcpy()/ strcpy()的性能,看看你得到了什么。

答案 4 :(得分:0)

我不确定你为什么要在这里使用引用。

这样做:

memcpy(two, one, sizeof(two));

请注意,您的用法更多是“字节数组”,尤其是unsigned。此外,如果您确实需要对这些字节进行“分组”,那么如果它们与典型的寄存器大小相匹配,您可以将它们分组为4s或8s。

答案 5 :(得分:0)

如果您遇到字符串复制问题,则始终使用llvm::StringRef方式:提供对不能更改它的基础字符串的引用。类属性仅限于char const*size_t

当然,缺点是您必须确保在StringRef

的使用期间保持分配底层缓冲区

答案 6 :(得分:0)

使用str *可能是在C中至少构建以null结尾的字符串的最简单方法。性能角度是在实际可能的副本之前,需要计算目标字符串中的目标位置(即找到的空字节的位置)。然后必须计算源字符串的长度以确保目标中有足够的内存。与使用memcpy相比,这会增加开销(字符串越长),你需要有足够大的缓冲区并跟踪你使用的字节数。

(如果编译器设置指定了2字节字符,则可能会有额外的复杂性)

因此,如果您的字符串长度为3000字节,并且您追加字符串“a”然后“b”,则每个字符串都需要扫描3000和3001字节,然后才能在“a”和“b”中写入两个字节( 'a'+ null和'b'+ null)。尝试优化它!在附加到3000字节字符串之前将“b”附加到“a”会快得多。

我个人会将memcpy用于大于50字节左右的目标字符串。代码变得有点复杂,但是一旦你做了几次就很容易了。