当前位置:  编程技术>c/c++/嵌入式

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

    来源: 互联网  发布时间:2014-10-18

    本文导语:  问题:函数memcpy(dest, src, sizeof(dest))、strncpy(dest, src, sizeof(dest))和snprintf(dest, sizeof(dest), "%s", src)都可以将src字符串中的内容拷贝到dest字符串中。哪一种方式效率最高呢?就是说,哪种方式性能最好呢?解决办法:1. 建立三个文件...

问题:
函数memcpy(dest, src, sizeof(dest))、strncpy(dest, src, sizeof(dest))和snprintf(dest, sizeof(dest), "%s", src)都可以将src字符串中的内容拷贝到dest字符串中。
哪一种方式效率最高呢?
就是说,哪种方式性能最好呢?
解决办法:
1. 建立三个文件test_memcpy.c,test_strncpy.c和test_snprintf.c:
文件test_memcpy.c:

代码如下:

david@u1110-hp:~/wrk/tmp/cstring$ cat test_memcpy.c
#include
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] = '';
 }
 return 0;
}

文件test_strncpy.c:
代码如下:

#include
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:
代码如下:

#include
#include
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. 分别编译三个文件:
代码如下:

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. 没有优化的情况下不同函数消耗时间对比:
代码如下:

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优化情况下不同函数消耗时间对比:

代码如下:

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$

代码如下:

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来进行优化,三个函数的耗时时间如下:
代码如下:

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()更高效。

    
 
 

您可能感兴趣的文章:

  • 字符串无法拷贝
  • c++面试题字符串拷贝函数示例
  • C++ Strings(字符串) 成员 Constructors:构造函数,用于字符串初始化
  • 怎样在使用curses字符串输出函数或字符输出函数时,隐藏光标
  • linux c下利用srand和rand函数生成随机字符串
  • Oracle 函数大全[字符串函数,数学函数,日期函数]第1/4页
  • php将html特殊字符转换成html字符串的函数:htmlspecialchars()介绍及代码举例
  • Linux下某些字符串操作函数没有对应的Unicode版本,有替代函数可用吗?
  • mysql中字符串和时间互相转换的方法(自动转换及DATE_FORMAT函数)
  • 计算一个字符串在另一字符串中出现的次数函数
  • Linux下C语言strstr()查找子字符串位置函数详细介绍(strstr原型、实现及用法)
  • 浅析MySQL之字符串函数
  • php将unix时间戳转换成字符串时间函数(date)
  • c语言 字符串函数 子串
  • shell函数如何返回字符串
  • sql函数实现去除字符串中的相同的字符串
  • C语言字符串函数库 Strfunc
  • linux下有没有清除字符串中空格的函数?
  • 标准C有没有截取字符串的函数?
  • 字符串IP转整型ip,怎么弄?有现成函数调用嘛?整型ip啥意思?
  • 去除字符串中的相同的字符串的sql函数
  • php字符串过滤与转换函数有哪些
  • Thinkphp模板中截取字符串函数简介
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • C++ Strings(字符串) 成员 size():返回字符串中字符的数量
  • 关于字符串的操作,我想得到字符串的长度,和他开始两位组成的新的字符串,例如::
  • C++ Strings(字符串) 成员 c_str():将字符串以C字符数组的形式返回
  • 如何使GDB显示完整的字符串变量,当字符串比较长时。
  • C++ Strings(字符串) 成员 empty():如果字符串为空,返回真
  • php判断字符串在另一个字符串位置的方法
  • C++ Strings(字符串) 成员 length():返回字符串的长度
  • sql函数实现去除字符串中的相同的字符串 iis7站长之家
  • C++ Strings(字符串) 成员 resize():重新设置字符串的大小
  • shell程序:在大文件中查找特定字符串,但该字符串可以跨行
  • C++ Strings(字符串) 成员 Operators:操作符,用于字符串比较和赋值
  • 怎样判断一个字符串在另一个字符串里面?
  • C++ Strings(字符串) 成员 reserve():保留一定容量以容纳字符串(设置capacity值)
  • 请问怎样从键盘读入一个字符串,怎样连接两个字符串,谢谢
  • C++ Strings(字符串) 成员 swap():交换两个字符串的内容
  • 浅析string类字符串和C风格字符串之间的区别
  • C++ Strings(字符串) 成员 find():在字符串中查找字符
  • 如何用shell实现将指定文件中的指定的字符串替换为我指定的另外的字符串
  • C++ Strings(字符串) 成员 substr():返回某个子字符串
  • 如何将一个双引号”放在一个字符串中,就是在字符串中如何转义一个双引号。谢谢!
  • C++ Strings(字符串) 成员 end():返回一个迭代器,指向字符串的末尾。(最后一个字符的下一个位置)
  • mysql查询字符串替换语句小结(数据库字符串替换)


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3