源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

字符串拷贝函数memcpy和strncpy以及snprintf 的性能比较

  • 时间:2021-08-13 00:25 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:字符串拷贝函数memcpy和strncpy以及snprintf 的性能比较
[b]问题: [/b]函数memcpy(dest, src, sizeof(dest))、strncpy(dest, src, sizeof(dest))和snprintf(dest, sizeof(dest), "%s", src)都可以将src字符串中的内容拷贝到dest字符串中。 [b]哪一种方式效率最高呢? [/b]就是说,哪种方式性能最好呢? [b]解决办法: [/b]1. 建立三个文件test_memcpy.c,test_strncpy.c和test_snprintf.c: 文件test_memcpy.c:
[u]复制代码[/u] 代码如下:
david@u1110-hp:~/wrk/tmp/cstring$ cat test_memcpy.c #include <string.h> int main(){  char src[] = "1234567890";  char dest[2048];  int len = 0;  for(int i = 0; i < 10000000; ++i){   memset(dest, 0, sizeof(dest));   len = strlen(src);   len = sizeof(dest) - 1 > len? len: sizeof(dest) -1;   memcpy(dest, src, len);   dest[len] = '\0';  }  return 0; }
文件test_strncpy.c:
[u]复制代码[/u] 代码如下:
#include <string.h> int main() {  char src[] = "1234567890";  char dest[2048];  int len = 0;  for(int i = 0; i < 10000000; ++i) {   memset(dest, 0, sizeof(dest));   strncpy(dest, src, sizeof(dest));  }  return 0; }
文件test_snprintf.c:
[u]复制代码[/u] 代码如下:
#include <stdio.h> #include <string.h> int main() {  char src[] = "1234567890";  char dest[2048];  int len = 0;  for(int i = 0; i < 10000000; ++i) {   memset(dest, 0, sizeof(dest));   snprintf(dest, sizeof(dest), "%s", src);  }  return 0; }
2. 分别编译三个文件:
[u]复制代码[/u] 代码如下:
david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -o test_memcpy test_memcpy.c david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -o test_strncpy test_strncpy.c david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -o test_snprintf test_snprintf.c
3. 没有优化的情况下不同函数消耗时间对比:
[u]复制代码[/u] 代码如下:
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_strncpy real 0m16.472s user 0m16.309s sys 0m0.036s david@u1110-hp:~/wrk/tmp/cstring$ time ./test_snprintf real 0m6.106s user 0m6.100s sys 0m0.000s david@u1110-hp:~/wrk/tmp/cstring$ time ./test_memcpy real 0m4.179s user 0m4.144s sys 0m0.000s david@u1110-hp:~/wrk/tmp/cstring$
从上面运行结果可以看出:没有任何优化的情况下,memcpy()和strncpy()性能相差4倍,snprintf()和strncpy()性能相差约2.5倍。 4.采用O3优化情况下不同函数消耗时间对比:
[u]复制代码[/u] 代码如下:
david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -O3 -o test_snprintf test_snprintf.c david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -O3 -o test_strncpy test_strncpy.c david@u1110-hp:~/wrk/tmp/cstring$ gcc -std=c99 -O3 -o test_memcpy test_memcpy.c david@u1110-hp:~/wrk/tmp/cstring$
[u]复制代码[/u] 代码如下:
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_strncpy real 0m16.178s user 0m16.161s sys 0m0.000s david@u1110-hp:~/wrk/tmp/cstring$ time ./test_snprintf real 0m6.242s user 0m6.032s sys 0m0.056s david@u1110-hp:~/wrk/tmp/cstring$ time ./test_memcpy real 0m3.567s user 0m3.436s sys 0m0.012s david@u1110-hp:~/wrk/tmp/cstring$
从上面运行结果可以看出:采用O3优化后,memcpy()和strncpy()性能相差近5倍,snprintf()和strncpy()性能相差基本不变约2.5倍。 5. 性能对比结论: 在需要用到字符串拷贝函数的时候,永远不要使用strncpy(),无论什么时候都用snprintf()来代替,而memcpy()是性能更好的实现方式。 strlen+memcpy也是linux内核的实现方式。 6. 意外收获结论: 将上述三个文件中的memset()改为用bzero()来实现数组的清零操作。 使用O3来进行优化,三个函数的耗时时间如下:
[u]复制代码[/u] 代码如下:
david@u1110-hp:~/wrk/tmp/cstring$ time ./test_strncpy real 0m14.395s user 0m13.929s sys 0m0.092s david@u1110-hp:~/wrk/tmp/cstring$ time ./test_snprintf real 0m3.785s user 0m3.772s sys 0m0.000s david@u1110-hp:~/wrk/tmp/cstring$ time ./test_memcpy real 0m1.241s user 0m1.236s sys 0m0.004s david@u1110-hp:~/wrk/tmp/cstring$
结论:仅仅换了一个清零函数,使得memcpy()和strncpy()的性能差别达到约12倍,而snprintf()和strncpy()的性能差别也达到约4倍。 就清零操作来说,bzero()远比memset()更高效。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部