snprintf与strncpy效率对比

一直以为strncpy效率优于snprintf. 无意中在网上看到snprintf效率大于strncpy,颇感震惊. 网址如下:

http://blog.csdn.net/wavemoon/archive/2009/12/06/4952904.aspx

后自己编码测试了下,发现情况复杂,并不是如此.

现在帖上我的测试:

环境: linux

编译器:g++

代码:

  1. #include <iostream>      
  2. #include <string.h>      
  3. #include <stdlib.h>      
  4. #include "sys/time.h"         
  5.      
  6.      
  7. const int LOOP_COUNT = 10000;      
  8.      
  9. class RecTime         
  10. {         
  11.     public:         
  12.         RecTime()         
  13.         {            
  14.             gettimeofday(&m_stBegin, NULL);         
  15.         }            
  16.         ~RecTime()         
  17.         {            
  18.             gettimeofday(&m_stEnd, NULL);      
  19.                   
  20.             int iUsedMs = (m_stEnd.tv_sec - m_stBegin.tv_sec)*1000 +      
  21.                             (m_stEnd.tv_usec-m_stBegin.tv_usec + 999) / 1000;      
  22.                   
  23.             std::cout << "time used: " << iUsedMs << std::endl;       
  24.         }            
  25.     private:         
  26.         struct timeval m_stBegin;      
  27.         struct timeval m_stEnd;         
  28. };         
  29.         
  30. void test_strncpy(char* pDst, int iDstLen, char* pSrc)         
  31. {         
  32.     RecTime _time_record;         
  33.     for(int i=0; i<LOOP_COUNT; i++)         
  34.     {            
  35.         if(pDst != strncpy(pDst, pSrc, iDstLen))         
  36.         {            
  37.             std::cout << "fatal error, strncpy failed.";      
  38.             exit(1);         
  39.         }      
  40.     }            
  41.     return ;         
  42. }         
  43.         
  44. void test_strncpy_withnull(char* pDst, int iDstLen, char* pSrc)         
  45. {         
  46.     RecTime _time_record;         
  47.     for(int i=0; i<LOOP_COUNT; i++)         
  48.     {            
  49.         if(pDst != strncpy(pDst, pSrc, iDstLen))         
  50.         {            
  51.             std::cout << "fatal error, strncpy failed.";      
  52.             exit(1);         
  53.         }      
  54.      
  55.         pDst[iDstLen - 1] = 0;      
  56.     }            
  57.     return ;         
  58. }       
  59.      
  60. void test_snprintf(char* pDst, int iDstLen, char* pSrc)         
  61. {         
  62.     RecTime _time_record;         
  63.     for(int i=0; i<LOOP_COUNT; i++)         
  64.     {         
  65.         if(0 > snprintf(pDst, iDstLen, "%s", pSrc))      
  66.         {         
  67.             std::cout << "fatal error, snprintf failed.";      
  68.             exit(1);         
  69.         }         
  70.     }         
  71.     return ;         
  72. }         
  73.      
  74. int main(int argc, char* argv[])         
  75. {         
  76.           
  77.     char szDst[1024] = {0};      
  78.     char szSrc[1024] = {0};      
  79.      
  80.          memset(szSrc, '1'sizeof(szSrc)-1);         
  81.          szSrc[sizeof(szSrc)-1] = 0;         
  82.      
  83.     char* pDst = szDst;      
  84.     int iDstSize = sizeof(szDst);      
  85.     char* pSrc = szSrc;      
  86.     int iSrcSize = sizeof(szSrc);      
  87.      
  88.     std::cout << "copy " << iSrcSize << " to "<< iDstSize << std::endl;      
  89.     std::cout << "snprintf ";      
  90.     test_snprintf(pDst, iDstSize, pSrc);         
  91.     std::cout << "strncpy ";      
  92.     test_strncpy(pDst, iDstSize, pSrc);         
  93.     /      
  94.      
  95.     return 0;         
  96. }     
#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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值