2

我正在编写一段代码,需要将值从一个 char 指针复制到另一个。主要要求是代码应该尽可能快地运行,并且可以在尽可能多的平台上运行。

我看到我可以使用以下两个函数之一来执行此字符串复制:

char * strncpy ( char * destination, const char * source, size_t num );

void * memcpy ( void * destination, const void * source, size_t num );

我如何确定最适合我的要求?

一般来说,我怎样才能找出两个不同功能(跨平台)的相对速度?

4

4 回答 4

6

他们不做同样的事情。如果您确定源缓冲区和目标缓冲区大小相同,请使用memcpy. 如果没有,strncpy进行绑定检查,这是要走的路。

但是,除非您进行数百万次操作,否则这不应该是您做出决定的因素。先做一些分析,看看你节省了多少时间(如果有的话)memcpy

于 2012-05-09T09:16:36.473 回答
3

从性能 POV 来看,memcpy速度更快,因为它不检查内容本身,只是复制它。

关于兼容性 - memcpy 是 C 标准的一部分。

于 2012-05-09T09:14:59.330 回答
2

如果您必须复制字符串(除非您事先知道它们的大小),您应该始终使用strncpy.

即使底层实现没有那么不同memcpy也会快得多,因为它不必检查它正在复制的内容,当它复制字符串字符()strncpy的结尾时会停止。NULL

编辑
关于性能的一些注意事项strncpymemcpy.
我们可以假设有两个 - 例如 - 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

于 2012-05-09T09:19:36.363 回答
1

您在此处选择的功能具有不同的功能。选择您需要的那个。

  • memcpy 将复制所有内容,并且两个缓冲区的大小必须相同
  • strncpy 将从较小的 c 字符串复制并用 /0 填充目标缓冲区的其余部分
  • strcpy 只会将字符串从目标复制到目标(但您应该使用安全变体之一)。

关于性能:memcpy 与 strncpy - memcpy 更快,但您需要知道输入字符串的大小。如果您的字符串大小变化很大, strcpy 可能是最快的,因为它在复制时确定了所需的大小。

于 2012-05-09T09:21:39.857 回答