- 浏览: 170315 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
boz.lee:
不错, 好多地方因为这里而出错
全局变量和局部变量在内存里的区别 -
issllx:
看到此文后对iteye深表遗憾
Yahoo S4 -
wohenshuaiba:
请问你有这个的代码吗?
k均值聚类(K-means) -
yxwang0615:
大神:
apr-1.3.3.tar.bz2
apr-util- ...
log4cxx编译方法 -
yxwang0615:
比csdn上的说的清楚干练,早看到这个就好了,我编了一天
p ...
log4cxx编译方法
一直以为strncpy效率优于snprintf. 无意中在网上看到snprintf效率大于strncpy,颇感震惊. 网址如下:
http://blog.csdn.net/wavemoon/archive/2009/12/06/4952904.aspx
后自己编码测试了下,发现情况复杂,并不是如此.
现在帖上我的测试:
环境: linux
编译器:g++
代码:
- #include <iostream>
- #include <string.h>
- #include <stdlib.h>
- #include "sys/time.h"
- const int LOOP_COUNT = 10000;
- class RecTime
- {
- public:
- RecTime()
- {
- gettimeofday(&m_stBegin, NULL);
- }
- ~RecTime()
- {
- gettimeofday(&m_stEnd, NULL);
- int iUsedMs = (m_stEnd.tv_sec - m_stBegin.tv_sec)*1000 +
- (m_stEnd.tv_usec-m_stBegin.tv_usec + 999) / 1000;
- std::cout << "time used: " << iUsedMs << std::endl;
- }
- private:
- struct timeval m_stBegin;
- struct timeval m_stEnd;
- };
- void test_strncpy(char* pDst, int iDstLen, char* pSrc)
- {
- RecTime _time_record;
- for(int i=0; i<LOOP_COUNT; i++)
- {
- if(pDst != strncpy(pDst, pSrc, iDstLen))
- {
- std::cout << "fatal error, strncpy failed.";
- exit(1);
- }
- }
- return ;
- }
- void test_strncpy_withnull(char* pDst, int iDstLen, char* pSrc)
- {
- RecTime _time_record;
- for(int i=0; i<LOOP_COUNT; i++)
- {
- if(pDst != strncpy(pDst, pSrc, iDstLen))
- {
- std::cout << "fatal error, strncpy failed.";
- exit(1);
- }
- pDst[iDstLen - 1] = 0;
- }
- return ;
- }
- void test_snprintf(char* pDst, int iDstLen, char* pSrc)
- {
- RecTime _time_record;
- for(int i=0; i<LOOP_COUNT; i++)
- {
- if(0 > snprintf(pDst, iDstLen, "%s", pSrc))
- {
- std::cout << "fatal error, snprintf failed.";
- exit(1);
- }
- }
- return ;
- }
- int main(int argc, char* argv[])
- {
- ////////////////////////////////////////////////////////////////////////////////////////////////////////
- char szDst[1024] = {0};
- char szSrc[1024] = {0};
- memset(szSrc, '1', sizeof(szSrc)-1);
- szSrc[sizeof(szSrc)-1] = 0;
- char* pDst = szDst;
- int iDstSize = sizeof(szDst);
- char* pSrc = szSrc;
- int iSrcSize = sizeof(szSrc);
- std::cout << "copy " << iSrcSize << " to "<< iDstSize << std::endl;
- std::cout << "snprintf ";
- test_snprintf(pDst, iDstSize, pSrc);
- std::cout << "strncpy ";
- test_strncpy(pDst, iDstSize, pSrc);
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- return 0;
- }
#include <iostream> #include <string.h> #include <stdlib.h> #include "sys/time.h" const int LOOP_COUNT = 10000; class RecTime { public: RecTime() { gettimeofday(&m_stBegin, NULL); } ~RecTime() { gettimeofday(&m_stEnd, NULL); int iUsedMs = (m_stEnd.tv_sec - m_stBegin.tv_sec)*1000 + (m_stEnd.tv_usec-m_stBegin.tv_usec + 999) / 1000; std::cout << "time used: " << iUsedMs << std::endl; } private: struct timeval m_stBegin; struct timeval m_stEnd; }; void test_strncpy(char* pDst, int iDstLen, char* pSrc) { RecTime _time_record; for(int i=0; i<LOOP_COUNT; i++) { if(pDst != strncpy(pDst, pSrc, iDstLen)) { std::cout << "fatal error, strncpy failed."; exit(1); } } return ; } void test_strncpy_withnull(char* pDst, int iDstLen, char* pSrc) { RecTime _time_record; for(int i=0; i<LOOP_COUNT; i++) { if(pDst != strncpy(pDst, pSrc, iDstLen)) { std::cout << "fatal error, strncpy failed."; exit(1); } pDst[iDstLen - 1] = 0; } return ; } void test_snprintf(char* pDst, int iDstLen, char* pSrc) { RecTime _time_record; for(int i=0; i<LOOP_COUNT; i++) { if(0 > snprintf(pDst, iDstLen, "%s", pSrc)) { std::cout << "fatal error, snprintf failed."; exit(1); } } return ; } int main(int argc, char* argv[]) { //////////////////////////////////////////////////////////////////////////////////////////////////////// char szDst[1024] = {0}; char szSrc[1024] = {0}; memset(szSrc, '1', sizeof(szSrc)-1); szSrc[sizeof(szSrc)-1] = 0; char* pDst = szDst; int iDstSize = sizeof(szDst); char* pSrc = szSrc; int iSrcSize = sizeof(szSrc); std::cout << "copy " << iSrcSize << " to "<< iDstSize << std::endl; std::cout << "snprintf "; test_snprintf(pDst, iDstSize, pSrc); std::cout << "strncpy "; test_strncpy(pDst, iDstSize, pSrc); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// return 0; }
输出:
copy 102400 to 102400
snprintf time used: 455
strncpy time used: 938
copy 10240 to 10240
snprintf time used: 42
strncpy time used: 94
copy 1024 to 1024
snprintf time used: 6
strncpy time used: 10
copy 64 to 64
snprintf time used: 2
strncpy time used: 1
copy 8 to 8
snprintf time used: 2
strncpy time used: 1
copy 1024 to 10240
snprintf time used: 6
strncpy time used: 104
copy 10240 to 1024
snprintf time used: 1234
strncpy time used: 10
copy 24 to 1024
snprintf time used: 2
strncpy time used: 11
copy 1024 to 24
snprintf time used: 136
strncpy time used: 1
分析:
1. 在源串长度和目标串长度一样大的情况下,效率几乎相同. 在一个数量级上. 因为在linux下snprintf末尾会有'\0'.所以这时推荐使用snprintf
2. 源串长度 < 目标串长度 snprintf效率领先一个级别, 这时推荐使用snprintf
3. 源串长度 > 目标串长度 strncpy效率领先一个级别, 这时推荐使用strncpy
结论:
1.在源串长度 远大于 目标串长度(至少几倍). 且效率重要的时候. 考虑使用strncpy(这时别忘了在末尾加'\0')
2.其他情况推荐使用snprintf
发表评论
-
小对象的分配技术
2011-03-21 12:01 1451小对象分配技术是Loki提高效率的有效途径,Loki里广 ... -
Techniques of Protocol Buffers Developer Guide
2010-12-07 10:39 1110Techniques Streaming Multip ... -
Protocol Buffer Basics: C++
2010-12-07 10:38 1024Protocol Buffer Basics: C++ ... -
Encoding of Protocol Buffers Developer Guide
2010-12-07 10:37 934Encoding A Simple Message ... -
Style Guide of Protocol Buffers Developer Guide
2010-12-07 10:36 777Style Guide This document pr ... -
Language Guide of Protocol Buffers Developer Guide
2010-12-07 10:34 1042Language Guide Defining A M ... -
Overview of Protocol Buffers Developer Guide
2010-12-07 10:31 672Developer Guide Welcome to t ... -
字节序
2010-12-01 21:03 943这几天又开始做网络方面的应用了,既然是网络编程,字节序肯定 ... -
全局变量和局部变量在内存里的区别
2010-11-09 21:55 2203一、预备知识—程序的内存分配 一个由c/C++编译 ... -
JobFlow要继续考虑的问题
2010-09-17 22:35 934小记: 1.把作业队列的概念扩展为作业池JobPool,提供 ... -
C++单例不可继承
2010-09-17 17:24 1476C++语言和单例的特性决定了单例不可继承。 单例有如下几项要 ... -
C++静态成员与静态成员函数小结
2010-09-16 15:48 1047类中的静态成员真是个让人爱恨交加的特性。我决定好好总结一下静态 ... -
log4cxx编译方法
2010-09-08 10:30 19731、下载http://logging.apache.o ... -
优秀的框架工具
2010-09-08 10:13 1125zookeeper Hadoop的子项目,可靠地分布式小文件 ... -
关于auto_ptr的忠告
2010-08-26 16:21 9091.auto_ptr不能用于数组,因为它调用的是delet ... -
用Valgrind查找内存泄漏和无效内存访问
2010-07-20 09:29 1946Valgrind是x86架构Linux上的多重用途代码剖析和内 ... -
头文件互包含于名字空间的相关问题
2010-07-17 20:27 1045c/c++里面头文件的使用 ... -
C++库介绍
2010-04-02 16:30 1498基础类1、 Dinkumware C++ ... -
C++中头文件相互包含的几点问题
2010-04-02 16:29 1014一、类嵌套的疑问 C++ ...
相关推荐
这里我们主要讨论三种常用的字符串拷贝函数:memcpy、strncpy和snprintf,并分析它们在不同情况下的性能表现。 首先,`memcpy`函数是C标准库中的一个通用内存拷贝函数,它并不关心源和目标是否为字符串,而是简单地...
在C语言中,`strncpy` 和 `snprintf` 都是用来进行字符串处理的函数,但它们有着不同的特性和用途。下面将详细分析这两个函数的用法和它们之间的区别。 `strncpy` 函数用于安全地复制字符串,其原型定义为: ```c ...
在实际编程中,理解和熟练使用这些clib字符串函数可以提高代码的可读性和效率。同时,注意处理字符串时的边界检查和内存管理,以避免潜在的安全问题。在编写涉及字符串操作的程序时,应始终考虑最佳实践,如使用`...
在C语言中,字符窜(字符串)是一种非常重要的...在实际编程中,理解并灵活运用这些函数,可以极大地提高代码的可读性和效率。请确保在使用时仔细阅读函数的文档,以确保正确理解和使用它们,避免潜在的问题和错误。
- `strncmp(s1, s2, n)` 与`strcmp()`类似,但它只比较前`n`个字符。 4. `strlen()` 函数: - `strlen(s)` 返回字符串`s`的长度,不包括结束的空字符。 5. `strchr()` 和 `strstr()` 函数: - `strchr(s, c)` ...
- 虽然不是标准C字符串函数,但`sprintf`或`snprintf`可用于将格式化的数据转换成字符串,类似于C++的`std::stringstream`。 9. **安全操作**: - `strncpy_s` 和 `strcpy_s`(Microsoft扩展):提供边界检查的...
2. 字符串处理函数:例如`strlen`计算字符串的长度,`strcpy`和`strncpy`用于复制字符串,`strcmp`比较两个字符串,`strcat`和`strncat`用于连接字符串,`strstr`查找子字符串在目标字符串中的位置。 3. 数组处理...
- `strcpy` 和 `strncpy`:用于复制字符串,`strcpy`不考虑目标字符串长度,`strncpy`可以指定最多复制的字符数。 - `strcat` 和 `strncat`:用于连接两个字符串,`strcat`不考虑目标字符串空间,`strncat`可以...
了解并熟练使用这些库函数是C++编程的基础,能够极大地提高编程效率,减少错误,并使代码更加简洁。在实际开发中,还需要注意选择合适的函数来处理特定任务,同时遵循良好的编程实践,如防止缓冲区溢出、确保内存...
这份速查资料能够帮助用户快速查找和理解各种函数的用途、参数以及返回值,提高编程效率。 1. 输入输出函数:如`printf`和`scanf`,是C语言中最基本的输入输出方式。`printf`用于格式化输出,可以处理整型、浮点型...
2. 字符串处理函数:`strlen`计算字符串长度,`strcpy`和`strncpy`用于复制字符串,`strcmp`比较两个字符串,`strcat`和`strncat`用于连接字符串。 3. 数组和内存管理函数:`malloc`和`free`进行动态内存分配与释放...
2. 字符串处理函数:包括`strlen`计算字符串长度,`strcpy`和`strncpy`用于复制字符串,`strcmp`比较字符串,`strcat`和`strncat`用于连接字符串,`strstr`查找子字符串等。 3. 数学运算函数:如`sqrt`计算平方根,...
在C语言库中,函数是其核心组成部分,它们提供了与操作系统和硬件交互的基本接口。下面我们将详细探讨几个重要的C语言库函数类别: 1. 输入/输出(I/O)函数: - `printf` 和 `scanf`:这是最常用的输入输出函数,...
3. 字符串处理:`strlen`计算字符串长度,`strcpy`和`strncpy`用于复制字符串,`strcmp`和`strncmp`进行字符串比较,`strcat`和`strncat`进行字符串连接。 4. 数学运算:`math.h`库包含了一系列数学函数,如平方根`...
2. **字符串处理**:`strlen`用于计算字符串的长度,`strcpy`和`strncpy`用于复制字符串,`strcmp`用于比较两个字符串,`strstr`则用于在一个字符串中查找子串。 3. **数学运算**:`math.h`头文件提供了大量的数学...
- **避免方法:** 使用 `strncpy` 函数,并确保目标缓冲区足够大,或者使用 `snprintf` 或 `strlcpy` 等更安全的函数。 4. **没有字符串结束符调用str开头的库函数的后果:** - 如果字符串没有正确结束,调用如 ...