如果您必须复制字符串(除非您事先知道它们的大小),您应该始终使用strncpy
.
即使底层实现没有那么不同memcpy
也会快得多,因为它不必检查它正在复制的内容,当它复制字符串字符()strncpy
的结尾时会停止。NULL
编辑
关于性能的一些注意事项strncpy
与memcpy
.
我们可以假设有两个 - 例如 - 512 字节的缓冲区,我们想要将内容(一个NULL
终止字符串 - 比如说 - 32 个字符)从第一个缓冲区复制到第二个缓冲区。
strncpy
将做什么:将一个字节一个字节地从源复制到目标。它会在复制NULL
字符时停止,然后将其他所有内容设置为 0。这是此功能的可能实现:
char *strncpy(char *dest, const char *src, size_t n)
{
char *ret = dest;
do {
if (!n--)
return ret;
} while (*dest++ = *src++);
while (n--)
*dest++ = 0;
return ret;
}
memcpy
将做什么:将所有内容从源文件批量复制到目标文件。这是此功能的可能实现:
void *memcpy(void *dest, const void *src, size_t n)
{
char *dp = dest;
const char *sp = src;
while (n--)
*dp++ = *sp++;
return dest;
}
即使两个版本都没有优化,您也可以看到它执行的操作要少得多,但只有当字符串长度比总缓冲区长度短得多时它才会变慢(它将保存*sp++
在第二个中while
)。所以即使是性能测试也不可靠,因为它取决于真实的输入(所以你应该有来自现实世界的某种统计数据)。
注意事项
此外,我们应该记住,真正的实现并不是那么简单!!!看看这个实现strncpy
:
http: //sourceware.org/git/ ?p=glibc.git;a=blob;f=string/strncpy.c;h=f6ee27832da95d9da9aef8a6fcf73f53f997c796;hb=HEAD
现在看看memcpy
实现:
http: //sourceware.org/git/ ?p=glibc.git;a=blob;f=string/memcpy.c;h=3080fcb4de4cec83a57b65bf07995a1e41abb1f6;hb=HEAD
memcpy
即使在我之前说过的极端情况下,也总是比strncpy
任何现实世界的情况都要快(看 PAGE_COPY_FWD_MAYBE)。
注意
这不是你的情况,因为你会大量使用它,但总的来说,我认为如果你必须复制一个字符串,那么使用 strncpy。总是。可能您在那里不需要任何性能提升,它会为您处理 NULL 终止符,并且总是很清楚您正在复制一个将读取您的代码的字符串。
您的情况不同,因为您确实进行了大量计算,那么如果知道缓冲区大小,则应该使用memcpy
它,因为它可能会快得多(特别是如果缓冲区不是很小)。
参考
Demo 实现来自:http
://clc-wiki.net/wiki/ memcpy 性能测试: http: //eetimes.com/design/embedded/4024961/Optimizing-Memcpy-improves-speed