`
ld_hust
  • 浏览: 170315 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

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

分享到:
评论

相关推荐

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

    这里我们主要讨论三种常用的字符串拷贝函数:memcpy、strncpy和snprintf,并分析它们在不同情况下的性能表现。 首先,`memcpy`函数是C标准库中的一个通用内存拷贝函数,它并不关心源和目标是否为字符串,而是简单地...

    strncpy与snprintf 的用法比较

    在C语言中,`strncpy` 和 `snprintf` 都是用来进行字符串处理的函数,但它们有着不同的特性和用途。下面将详细分析这两个函数的用法和它们之间的区别。 `strncpy` 函数用于安全地复制字符串,其原型定义为: ```c ...

    clib字符串函数使用

    在实际编程中,理解和熟练使用这些clib字符串函数可以提高代码的可读性和效率。同时,注意处理字符串时的边界检查和内存管理,以避免潜在的安全问题。在编写涉及字符串操作的程序时,应始终考虑最佳实践,如使用`...

    C语言字符窜函数大全

    在C语言中,字符窜(字符串)是一种非常重要的...在实际编程中,理解并灵活运用这些函数,可以极大地提高代码的可读性和效率。请确保在使用时仔细阅读函数的文档,以确保正确理解和使用它们,避免潜在的问题和错误。

    c语言中所有字符串函数使用手册

    - `strncmp(s1, s2, n)` 与`strcmp()`类似,但它只比较前`n`个字符。 4. `strlen()` 函数: - `strlen(s)` 返回字符串`s`的长度,不包括结束的空字符。 5. `strchr()` 和 `strstr()` 函数: - `strchr(s, c)` ...

    c字符串解析处理功能函数集

    - 虽然不是标准C字符串函数,但`sprintf`或`snprintf`可用于将格式化的数据转换成字符串,类似于C++的`std::stringstream`。 9. **安全操作**: - `strncpy_s` 和 `strcpy_s`(Microsoft扩展):提供边界检查的...

    C语言库函数功能查询器

    2. 字符串处理函数:例如`strlen`计算字符串的长度,`strcpy`和`strncpy`用于复制字符串,`strcmp`比较两个字符串,`strcat`和`strncat`用于连接字符串,`strstr`查找子字符串在目标字符串中的位置。 3. 数组处理...

    C语言库函数集合

    - `strcpy` 和 `strncpy`:用于复制字符串,`strcpy`不考虑目标字符串长度,`strncpy`可以指定最多复制的字符数。 - `strcat` 和 `strncat`:用于连接两个字符串,`strcat`不考虑目标字符串空间,`strncat`可以...

    C++常用库函数 缓冲区操作函数、字符分类函数、数据转换函数、数学函数、输入和输出函数、进程控制函数、字符串操作函数

    了解并熟练使用这些库函数是C++编程的基础,能够极大地提高编程效率,减少错误,并使代码更加简洁。在实际开发中,还需要注意选择合适的函数来处理特定任务,同时遵循良好的编程实践,如防止缓冲区溢出、确保内存...

    C语言函数库速查

    这份速查资料能够帮助用户快速查找和理解各种函数的用途、参数以及返回值,提高编程效率。 1. 输入输出函数:如`printf`和`scanf`,是C语言中最基本的输入输出方式。`printf`用于格式化输出,可以处理整型、浮点型...

    C语言库函数使用大全

    2. 字符串处理函数:`strlen`计算字符串长度,`strcpy`和`strncpy`用于复制字符串,`strcmp`比较两个字符串,`strcat`和`strncat`用于连接字符串。 3. 数组和内存管理函数:`malloc`和`free`进行动态内存分配与释放...

    C语言库函数C语言库函数C语言库函数

    2. 字符串处理函数:包括`strlen`计算字符串长度,`strcpy`和`strncpy`用于复制字符串,`strcmp`比较字符串,`strcat`和`strncat`用于连接字符串,`strstr`查找子字符串等。 3. 数学运算函数:如`sqrt`计算平方根,...

    C语言库函数大全(HTML帮助文件格式)

    在C语言库中,函数是其核心组成部分,它们提供了与操作系统和硬件交互的基本接口。下面我们将详细探讨几个重要的C语言库函数类别: 1. 输入/输出(I/O)函数: - `printf` 和 `scanf`:这是最常用的输入输出函数,...

    Linux 常用C函数(中文版HTML版)

    3. 字符串处理:`strlen`计算字符串长度,`strcpy`和`strncpy`用于复制字符串,`strcmp`和`strncmp`进行字符串比较,`strcat`和`strncat`进行字符串连接。 4. 数学运算:`math.h`库包含了一系列数学函数,如平方根`...

    C函数速查手册.zip

    2. **字符串处理**:`strlen`用于计算字符串的长度,`strcpy`和`strncpy`用于复制字符串,`strcmp`用于比较两个字符串,`strstr`则用于在一个字符串中查找子串。 3. **数学运算**:`math.h`头文件提供了大量的数学...

    深入学习C语言知识点checklist

    - **避免方法:** 使用 `strncpy` 函数,并确保目标缓冲区足够大,或者使用 `snprintf` 或 `strlcpy` 等更安全的函数。 4. **没有字符串结束符调用str开头的库函数的后果:** - 如果字符串没有正确结束,调用如 ...

Global site tag (gtag.js) - Google Analytics