memset效率测试

刚刚AC了一题,需要将数组部分初始化为零,为了简单我就用memset将整个数组置零了,在我印象中memset函数的速度是快得惊人的,没想到居然超时了,让我不得不重新审视memset的效率和我那想当然的愚昧。

初始化部分如下:#include<stdio.h> #define MAX 1000 int ndata[ MAX ][ MAX ]; int main() { char a[MAX]; char b[MAX]; int i , j; int nTemp = 10000; i = nTemp, j = nTemp; double BegTime , EndTime; BegTime = clock(); while( i-- ) { memset( ndata, 0, sizeof(int) * MAX * MAX ); } EndTime = clock(); printf(" %g s \n ", (EndTime - BegTime ) / 1000/1000); BegTime = clock(); while( nTemp-- ) { for ( i = 0; i <= MAX; i++) ndata[i][0] = 0; for ( j = 0; j <= MAX; j++) ndata[0][j] = 0; } EndTime = clock(); printf(" %g s \n ", (EndTime - BegTime ) / 1000/1000); return 0; }

3.75s

0.11s

速度相差了三十倍,难怪会超时,为了知道memset的效率,又试了下如下案例


#include<stdio.h> #define MAX 1000 int ndata[ MAX ][ MAX ]; int main() { char a[MAX]; char b[MAX]; int i , j; int nTemp = 10000; i = nTemp, j = nTemp; double BegTime , EndTime; BegTime = clock(); while( i-- ) { memset( ndata, 0, sizeof(int) * MAX * MAX ); } EndTime = clock(); printf(" %g s \n ", (EndTime - BegTime ) / 1000/1000); BegTime = clock(); while( nTemp-- ) { /* for ( i = 0; i <= MAX; i++) ndata[i][0] = 0; for ( j = 0; j <= MAX; j++) ndata[0][j] = 0; */ for ( i = 0; i < MAX; i++) for ( j = 0; j < MAX; j++) ndata[i][j] = 0; } EndTime = clock(); printf(" %g s \n ", (EndTime - BegTime ) / 1000/1000); return 0; }
上述代码就为了初始化一个大数组,执行结果如下:

3.58s

24.8s


测试结果表明:memset比普通的初始化快7倍,所以应该多用memset来完成初始化工作。但,最根本还是应该减少计算机的计算量。

### C++ 中 `memset` 和 `vector` 的使用场景与性能对比 #### 使用场景分析 `memset` 是一种用于操作连续内存区域的低级工具,通常用来快速初始化数组或结构体的内容为特定值(通常是 0 或 -1)。它适用于需要高效处理原始内存的情况[^2]。 相比之下,`std::vector` 是 C++ 标准库提供的一种动态数组容器。它的设计目标是简化程序员的操作并增强安全性。通过封装底层实现细节,`vector` 提供了许多便利的方法来管理数据集合,例如动态调整大小、迭代器支持以及范围检查等功能[^3]。 对于简单的数值初始化任务来说,如果只是单纯追求效率而无需额外功能,则可以直接采用 `memset`;但如果涉及到复杂的数据类型或者希望利用 STL 容器带来的优势时,应该选择 `vector` 及其相关算法如 `fill` 来完成相同的工作。 #### 性能差异探讨 当针对整型数组执行批量设置操作时,在某些编译环境下可能会发现 `memset` 的运行速度优于 `std::fill` 方法。这是因为前者能够直接调用 CPU 层面指令集来进行优化后的复制动作,从而减少了循环次数和条件判断开销。 不过需要注意的是这种差距并非绝对存在——现代编译器往往会对标准模板库中的成员函数做高度内联展开以及其他形式上的改进措施,使得最终生成的目标代码也可能达到接近甚至超越手写版本的效果。因此实际应用中不应仅凭理论推测就断定某一方一定更快,而是应当依据具体环境测试得出结论。 另外值得注意的一点在于:尽管单次调用 `memset` 设置整个缓冲区可能显得更加简洁明快,但它无法灵活应对非零常量以外的各种需求;反观基于迭代逻辑构建起来的标准算法族则完全没有此类局限性约束,允许用户自定义任意复杂的赋值模式。 ```cpp #include <iostream> #include <vector> #include <cstring> // For memset #include <algorithm> // For std::fill void example_memset() { int array[10]; memset(array, 0, sizeof(array)); // Efficiently sets all elements to zero. } void example_vector_fill() { std::vector<int> vec(10); std::fill(vec.begin(), vec.end(), 42); // Sets each element of the vector to 42. } ``` 综上所述,虽然在一些特殊情况下 `memset` 可能在性能上有微弱领先,但从长远来看还是推荐尽可能多地依赖更高层次抽象所提供的解决方案 —— 这不仅有助于提升程序整体质量水平,而且还能让维护工作变得更加轻松愉快^.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值