Snprintf Strncpy Memcpy Strlcpy各自的特点
来源:互联网 发布:旅游软件有哪些 编辑:程序博客网 时间:2024/05/17 01:13
Snprintf Strncpy Memcpy Strlcpy各自的特点
在做一个大型系统的性能优化时,字符串拷贝都能在性能消耗方面占据相当比重,选择合适的字符串处理函数,至少能避免一些无谓的性能消耗。通常接触的字符串拷贝函数有这么些:snprintf strncpy memcpy strlcpy
。考虑的核心问题就是高效和安全。
snprintf
int snprintf(char *str, size_t size, const char *format, ...);
通过snprintf(dst_str, dst_size, "%s", source_str);
可以将source_str拷贝到dst_str。snprintf的特点是安全,不管怎么着,它都能保证结果串str以\0结尾,哪怕dst_size不够大,它都能做好截断,同时在末尾添加上\0。在性能方面,当source_str远长于dst_size时,该函数却很低效的,其他情况下该函数即安全又高效。之所以当source_str远长于dst_size时,该函数低效,是因为该函数的返回值为source_str的长度,那么它就必须将source_str全部过一遍,哪怕并不拷贝到dst_str中去。注意,当source_str长度比dst_size小时,它不会把末尾的多余字符置零,所以它是很高效的,不会多做无用功。
strncpy
char *strncpy(char *dest, const char *src, size_t n);
strncpy比strcpy安全稍微安全点,strncpy顶多拷贝n个字节,所以在dest不够的情况下,不会像strcpy出现拷贝越界。但也只是稍微安全点而已,如果src长度比n大,那么dest就不是以\0结尾的了,所以通常要这么使用:
strncpy(buf, str, n);if (n > 0) { buf[n - 1]= '\0';}
在高效方面strncpy也做得不好,它的大致实现这样的:
char *strncpy(char *dest, const char *src, size_t n){ size_t i; for (i = 0; i < n && src[i] != '\0'; i++) { dest[i] = src[i]; } for ( ; i < n; i++) { dest[i] = '\0'; } return dest;}
也就是说,当src长度比n小时,未使用的字符,它会帮你填充为0,但我们往往会开一个大的Buffer来接收数据,如此必然有大量的多余空间,这样不仅速度慢,而且还会导致实存的消耗上涨。总之,strncpy的即不怎么安全,也不怎么高效。
memcpy
void *memcpy(void *dest, const void *src, size_t n);
很明显memcpy不安全,它只是做简单的拷贝而已,不过它很高效,如果你能保证不会越界的话,就使用memcpy吧。之前跟一些人沟通,居然有人以为memcpy的高效是因为使用什么特别的内核函数或者硬件指令,看样子还是有人对memcpy不理解,所以会想太多,其实memcpy的实现就是一个一个赋值,strcpy也是一个一个赋值,不过,memcpy做了点优化,64位机器下,它会64位64位地拷贝,即8个字节8个字节地拷贝,对于除8的余数,再做单独处理,而strcpy是一个字节一个字节地拷贝,所以当有大量字符串需要拷贝时,理论上memcpy会比strcpy快8倍。如果用sse sse2之类的128位指令来实现,可以拷贝得更快,实现起来也不难,但gnu std标准库得做得通常,不可能去考虑各种高端CPU来写代码。
strlcpy
size_t strlcpy(char *dst, const char *src, size_t size);
某些平台上会有strlcpy的库函数,但是咱正常使用的gcc库是没有这个函数的,其实就是对snprintf和strncpy的缺陷做了弥补,即保证安全,又保证高效。就不讲的。
其实理解好snprintf和strncpy本身的特点,就够用了,假如能确保安全,那么使用strcpy或者memcpy都是更好的选择。总之,理解清楚原理才是最重要的。
- Snprintf Strncpy Memcpy Strlcpy各自的特点
- strcpy ,strncpy ,strlcpy, snprintf, memcpy 用法、区别和效率
- strcpy ,strncpy ,strlcpy和snprintf的使用
- strcpy,strncpy,strlcpy,memcpy
- strcpy,strncpy,strlcpy,memcpy
- strcpy,strncpy,strlcpy,memcpy
- strcpy,strncpy,strlcpy,memcpy
- strcpy,strncpy,strlcpy,memcpy 用法
- strcpy, strncpy, strlcpy的区别
- strcpy ,strncpy ,strlcpy的用法
- strcpy ,strncpy ,strlcpy的用法
- strcpy ,strncpy ,strlcpy的用法
- 字符串拷贝函数memcpy和strncpy以及snprintf 的性能比较
- 字符串拷贝函数memcpy和strncpy以及snprintf 的性能比较
- strncpy,snprintf,strnlen的用法
- error C4996 & strcpy ,strncpy ,strlcpy的用法
- 字符串拷贝函数memcpy()、strncpy()和snprintf()性能之比较
- 字符串拷贝函数memcpy()、strncpy()和snprintf()性能之比较
- window.open详解
- RedHat Enterprise Linux 5 NFS服务器
- windows oracle EM的安装配置
- 死锁的原因、条件和避免死锁的方法
- 错误2error LNK2019: 无法解析的外部符号 "public: __thiscall obj3dModel::~obj3dModel(void)" (??1obj3dModel@@QAE
- Snprintf Strncpy Memcpy Strlcpy各自的特点
- Java设计模式之 —— 单例(Singleton)
- Rumor Diffusion and Convergence during the 3.11 Earthquake: A Twitter Case Study
- wireshark网络包分析软件安装
- Mac下android_sdk配置环境变量
- ubuntu 编译opencv2.4.10
- Sqlite数据库中的数据类型及字符串比较
- JAVA中GBK转UTF-8
- CopyOnWriteArrayList操作java.lang.UnsupportedOperationException