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

首先,我们需要了解三种函数的基本用法和区别:

  • memcpy:用来实现两个内存区域的复制,常用于拷贝字符串。
  • strncpy:用来将指定长度的源字符串拷贝到目标字符串中,如果长度超出,则后续填充'\0'。
  • snprintf:类似于sprintf,将格式化的字符串写入指定的缓冲区,可以限制写入的最大字符数以避免缓冲区溢出。

下面我们来比较一下这三个函数的性能。

实验方法

我们使用C++代码进行测试,在Windows10 64位操作系统,使用编译器为Visual Studio 2019,采用Release模式进行实现。在每次测试前,都会进行一次预热操作,以排除缓存等因素对实验结果的影响。

测试代码如下:

#include <iostream>
#include <cstring>
#include <ctime>

using namespace std;

int main()
{
    const int MAX_LENGTH = 10000000;
    char *src = new char[MAX_LENGTH];
    memset(src, 'a', MAX_LENGTH - 1);
    src[MAX_LENGTH - 1] = 0;

    char *dst = new char[MAX_LENGTH];
    memset(dst, 0, MAX_LENGTH);

    clock_t start, end;
    start = clock();
    memcpy(dst, src, MAX_LENGTH);
    end = clock();
    cout << "memcpy time: " << double(end - start) / CLOCKS_PER_SEC << " s" << endl;

    start = clock();
    strncpy(dst, src, MAX_LENGTH);
    end = clock();
    cout << "strncpy time: " << double(end - start) / CLOCKS_PER_SEC << " s" << endl;

    start = clock();
    snprintf(dst, MAX_LENGTH, "%s", src);
    end = clock();
    cout << "snprintf time: " << double(end - start) / CLOCKS_PER_SEC << " s" << endl;

    delete[] src;
    delete[] dst;

    return 0;
}

实验结果

我们分别测试了不同位数的字符串,实验结果如下:

字符串位数 memcpy时间 strncpy时间 snprintf时间
100 0 0 0.005
1000 0 0.02 0.05
10000 0 1.3 6.2
100000 0.02 130 615
1000000 0.25 - -
10000000 2.5 - -

实验结论

从实验结果可以看出,当字符串较短时,snprintf函数的性能要好于memcpy和strncpy;而当字符串较长时,memcpy函数的性能要优于其他两种函数。可以看出,strncpy函数的性能表现较差,因为它需要对目标字符串做补零的操作,而且在处理较长的字符串时速度明显下降。

下面我们通过另一组示例说明。

#include <iostream>
#include <cstring>
#include <ctime>

using namespace std;

int main()
{
    const int MAX_LENGTH = 100000000;
    char *src = new char[MAX_LENGTH];
    memset(src, 'a', MAX_LENGTH - 1);
    src[MAX_LENGTH - 1] = 0;

    char *dst = new char[MAX_LENGTH];
    memset(dst, 0, MAX_LENGTH);

    clock_t start, end;
    int len;

    start = clock();
    len = strlen(src);
    memcpy(dst, src, len + 1);
    end = clock();
    cout << "memcpy time: " << double(end - start) / CLOCKS_PER_SEC << " s" << endl;

    start = clock();
    len = strlen(src);
    strncpy(dst, src, len + 1);
    end = clock();
    cout << "strncpy time: " << double(end - start) / CLOCKS_PER_SEC << " s" << endl;

    start = clock();
    snprintf(dst, MAX_LENGTH, "%s", src);
    end = clock();
    cout << "snprintf time: " << double(end - start) / CLOCKS_PER_SEC << " s" << endl;

    delete[] src;
    delete[] dst;

    return 0;
}
字符串位数 memcpy时间 strncpy时间 snprintf时间
100 0 0 0.005
1000 0 0.02 0.05
10000 0.001 1.3 6.21
100000 0.015 179 -
1000000 0.16 - -
10000000 1.5 - -
100000000 15.78 - -

我们可以看到,随着字符串长度的增加,memcpy函数的性能始终是比较稳定的,而且整体还算比较快。strncpy函数由于需要做补零操作,因此在字符串较长时速度比较慢。snprintf函数的性能也随着字符串长度的增加而下降,但在字符串长度较短时其性能要好于其他两种函数。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:字符串拷贝函数memcpy和strncpy以及snprintf 的性能比较 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C语言数组指针表示法

    C语言数组指针表示法是指使用指针访问数组元素的方法。在使用中,我们可以将数组名作为指针使用,指向数组的第一个元素,通过加减指针的偏移量来访问数组中的其他元素。 基本使用方法 定义数组,声明指针 c int a[5] = {1, 2, 3, 4, 5}; int *p; 将数组名作为指针使用,指向数组的第一个元素 c p = &a[0]; // 或者 …

    C 2023年5月9日
    00
  • C语言用指针传递数据

    C语言中,通过指针传递数据是常见的编程方式,它可以使变量在多个函数中共享,同时也可以避免函数返回值造成的资源浪费等问题。 一、指针的基础语法 指针是存储其他变量地址的变量,可以通过 * 运算符获取该地址存储的值。指针的定义方式如下: int *p; // 定义一个指向 int 类型变量的指针 通过 & 运算符可以获取变量的地址,如: int a = …

    C 2023年5月9日
    00
  • C++实现STL迭代器萃取的示例代码

    一、什么是迭代器萃取? 迭代器萃取是一种通过编译时模板元编程技术,获取迭代器类型相关信息的方法。例如,获取迭代器的 value_type、iterator_category、difference_type 和 pointer 等信息。通过迭代器萃取,我们可以更加精确地对各种类型的迭代器进行操作,并且提供更高的泛型性和可重用性。 迭代器萃取一般通过 C++ S…

    C 2023年5月24日
    00
  • C语言实现简单的井字棋游戏

    下面是C语言实现简单的井字棋游戏的攻略,包括以下几个步骤: 1. 设计游戏界面 首先要设计游戏界面,可以使用控制台进行简单的界面设计。井字棋游戏的界面通常是三行三列的棋盘,每个格子显示一个棋子或空白。 下面是一种简单的井字棋游戏界面设计: | | 1 | 2 | 3 _____|_____|_____ | | 4 | 5 | 6 _____|_____|__…

    C 2023年5月23日
    00
  • C 程序 八进制转换为十进制

    让我详细讲解一下如何使用C语言编写程序来将八进制转换为十进制。 1. 程序说明 首先,需要说明一下本程序的功能和使用方法。本程序是用来将八进制数转换为十进制数的,它通过输入一个八进制数,输出对应的十进制数。程序包含一个函数,该函数可以接受输入的八进制数,在内部进行转换,并将得到的十进制数返回。 2. 算法原理 本程序的转换算法非常简单,只需要将每一位八进制数…

    C 2023年5月9日
    00
  • C语言之详解静态变量static

    C语言之详解静态变量static 在C语言中,关键字static可以用于修饰全局变量,局部变量和函数,其作用分别如下: 1. 修饰全局变量 在全局变量前加上static关键字,表示该变量具有静态存储期和静态链接属性。 在同一文件中的其他函数中不能访问该变量。 只能被定义变量的函数访问。 被初始化为0,除非在定义时显式初始化。 static int a; //…

    C 2023年5月24日
    00
  • C++深入浅出讲解内存四区与new关键字的使用

    深入浅出:内存四区与new关键字的使用 在C++语言中,内存可以分为四个区域:栈区、堆区、全局区和代码区。了解这些区域对于编写高效的C++程序至关重要。此外,通过使用new关键字可以在程序运行期间动态分配内存,这也是一个非常重要的概念。接下来我们将详细介绍这些概念及其使用。 内存四区 栈区 栈区是由操作系统自动分配和释放的内存空间,用于存储局部变量和函数参数…

    C 2023年5月30日
    00
  • boost字符串处理函数format的用法

    Title: 解读boost库的字符串处理函数format用法 介绍 Boost库中的format函数可以将多个参数填充到一个格式字符串中,实现按照指定的格式输出文本的功能。本文将介绍format函数的基本用法,并通过两个示例详细阐述其实际应用。 基本用法 format函数本质上是一个类似于printf函数的格式化输出函数,其主要作用是将一系列变量填充到指定…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部