Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >bzero和memset哪个更耗时_malloc_trim

bzero和memset哪个更耗时_malloc_trim

作者头像
全栈程序员站长
发布于 2022-11-07 09:18:58
发布于 2022-11-07 09:18:58
9650
举报

关于字符数组的初始化,在项目的压力测试中,发现性能明显下降,变怀疑在程序中的若干临时字符数组的初始化(使用bzero)身上。于是修改为首个字符置 零的方式而非全部置零的方式初始化,响应得到明显的提升。原来在mp3检索的每一条结果都要进行bzero对临时数组初始化,每一个请求需要30次的 bzero对临时数组的置零。于是想到了,在非必要的情况下,只对临时数组的第一个(或前几个)字符置零的初始化方式对比与使用bzero的话,能够明显 提高性能。

在此之外,又想起另外两种对数组所有字节都置零的方式,顺便比较一下他们之间的性能,写个简单的程序如下:

#include <stdio.h> #include <sys/time.h> #include <string.h>

#define TIMEDIFF(s, e) (((e.tv_sec)-(s.tv_sec))*1000000 + (e.tv_usec) – (s.tv_usec))

int main() { struct timeval s, e; char a[1024], b[1024*1024], c[1024*1024*4];

gettimeofday(&s, NULL); bzero(a, sizeof(a)); gettimeofday(&e, NULL); printf(“bzero 1k: %d/n”, TIMEDIFF(s, e));

gettimeofday(&s, NULL); bzero(b, sizeof(b)); gettimeofday(&e, NULL); printf(“bzero 1m: %d/n”, TIMEDIFF(s, e));

gettimeofday(&s, NULL); bzero(c, sizeof(c)); gettimeofday(&e, NULL); printf(“bzero 4M: %d/n”, TIMEDIFF(s, e));

gettimeofday(&s, NULL); memset(a, 0, sizeof(a)); gettimeofday(&e, NULL); printf(“memset 1k: %d/n”, TIMEDIFF(s, e));

gettimeofday(&s, NULL); memset(b, 0, sizeof(b)); gettimeofday(&e, NULL); printf(“memset 1M: %d/n”, TIMEDIFF(s, e));

gettimeofday(&s, NULL); memset(c, 0, sizeof(c)); gettimeofday(&e, NULL); printf(“memset 4M: %d/n”, TIMEDIFF(s, e));

gettimeofday(&s, NULL); for(int i=0; i<sizeof(a); ++i) a[i]=0; gettimeofday(&e, NULL); printf(“for 1k: %d/n”, TIMEDIFF(s, e));

gettimeofday(&s, NULL); for(int i=0; i<sizeof(b); ++i) b[i]=0; gettimeofday(&e, NULL); printf(“for 1M: %d/n”, TIMEDIFF(s, e));

gettimeofday(&s, NULL); memset(c, 0, sizeof(c)); gettimeofday(&e, NULL); printf(“memset 4M: %d/n”, TIMEDIFF(s, e));

gettimeofday(&s, NULL); for(int i=0; i<sizeof(a); ++i) a[i]=0; gettimeofday(&e, NULL); printf(“for 1k: %d/n”, TIMEDIFF(s, e));

gettimeofday(&s, NULL); for(int i=0; i<sizeof(b); ++i) b[i]=0; gettimeofday(&e, NULL); printf(“for 1M: %d/n”, TIMEDIFF(s, e));

gettimeofday(&s, NULL); for(int i=0; i<sizeof(c); ++i) c[i]=0; gettimeofday(&e, NULL); printf(“for 4M: %d/n”, TIMEDIFF(s, e)); }

运行的结果基本上是,在数组较小的情况下,bzero的效率比memset高;当数组超过一定大小之后,bzero的效率开始比memset低;数组越 大,memset的性能优势越明显。而在数组较小的情况下,memset的性能甚至不如直接for循环对数组中的每一个字节置零的方法。

以下的运行结果的数值单位是微秒(gettimeofday的默认单位)。

第一次运行: bzero 1k: 6 bzero 1m: 2168 bzero 4M: 9136 memset 1k: 11 memset 1M: 1303 memset 4M: 5483 for 1k: 12 for 1M: 4934 for 4M: 21313

再一次运行: bzero 1k: 6 bzero 1m: 2160 bzero 4M: 9067 memset 1k: 17 memset 1M: 1257 memset 4M: 5115 for 1k: 11 for 1M: 4866 for 4M: 19201

此后,又写了个小程序,测试在堆上的数组中,bzero和memset的效率,发现两者差不多。可能由于,里面原来的数据就比较有规则,不管是否先对数组置一随机值。(malloc开辟字符数组空间时,会清零的。)

#include <stdio.h> #include <string.h> #include <sys/time.h> #include <stdlib.h> #include <time.h>

#define TIMEDIFF(s, e) (((e.tv_sec)-(s.tv_sec))*1000000 + (e.tv_usec) – (s.tv_usec))

int main() { srand(time(NULL)); char *array; struct timeval s, e; int tb, tm; for(int i=1; i<1024*1024*1024; i*=2) { array=(char*)malloc(i); memset(array, rand()%256, i); gettimeofday(&s, NULL); bzero(array, i); gettimeofday(&e, NULL); tb=TIMEDIFF(s, e); free(array);

array=(char*)malloc(i); memset(array, rand()%256, i); gettimeofday(&s, NULL); memset(array, 0, i); gettimeofday(&e, NULL); tm=TIMEDIFF(s, e); free(array);

printf(“array size: %d /tbzero time: %d /tmemset time: %d /tbzero>memset?: %d/n”, i, tb, tm, (tb>tm));

} }

运行结果: array size: 1 bzero time: 28 memset time: 1 bzero>memset?: 1 array size: 2 bzero time: 1 memset time: 1 bzero>memset?: 0 array size: 4 bzero time: 1 memset time: 1 bzero>memset?: 0 array size: 8 bzero time: 1 memset time: 1 bzero>memset?: 0 array size: 16 bzero time: 1 memset time: 1 bzero>memset?: 0 array size: 32 bzero time: 1 memset time: 1 bzero>memset?: 0 array size: 64 bzero time: 1 memset time: 0 bzero>memset?: 1 array size: 128 bzero time: 1 memset time: 1 bzero>memset?: 0 array size: 256 bzero time: 1 memset time: 1 bzero>memset?: 0 array size: 512 bzero time: 1 memset time: 1 bzero>memset?: 0 array size: 1024 bzero time: 1 memset time: 1 bzero>memset?: 0 array size: 2048 bzero time: 1 memset time: 1 bzero>memset?: 0 array size: 4096 bzero time: 2 memset time: 2 bzero>memset?: 0 array size: 8192 bzero time: 2 memset time: 2 bzero>memset?: 0 array size: 16384 bzero time: 5 memset time: 6 bzero>memset?: 0 array size: 32768 bzero time: 9 memset time: 8 bzero>memset?: 1 array size: 65536 bzero time: 27 memset time: 24 bzero>memset?: 1 array size: 131072 bzero time: 81 memset time: 68 bzero>memset?: 1 array size: 262144 bzero time: 190 memset time: 169 bzero>memset?: 1 array size: 524288 bzero time: 447 memset time: 393 bzero>memset?: 1 array size: 1048576 bzero time: 996 memset time: 973 bzero>memset?: 1 array size: 2097152 bzero time: 2258 memset time: 2272 bzero>memset?: 0 array size: 4194304 bzero time: 4821 memset time: 4799 bzero>memset?: 1 array size: 8388608 bzero time: 9797 memset time: 9799 bzero>memset?: 0 array size: 16777216 bzero time: 19764 memset time: 19737 bzero>memset?: 1 array size: 33554432 bzero time: 39687 memset time: 39675 bzero>memset?: 1 array size: 67108864 bzero time: 79907 memset time: 79324 bzero>memset?: 1 array size: 134217728 bzero time: 158956 memset time: 158775 bzero>memset?: 1 array size: 268435456 bzero time: 318247 memset time: 318632 bzero>memset?: 0 array size: 536870912 bzero time: 638536 memset time: 638883 bzero>memset?: 0

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/183529.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
掌握异步日志:解锁日志系统的效率和性能
通过notify和超时方式唤醒日志落盘线程读取日志写入磁盘。 多线程间使用mutex互斥保证线程安全。 日志写入磁盘时采用批量写入方式。
Lion Long
2024/11/01
1330
掌握异步日志:解锁日志系统的效率和性能
http协议户端下载流程
/************************************************************************************** 功能:http协议客户端网络下载测试 时间:2014-03-09 version : V1.0 说明:http协议客户端工作要点 1.创建socketbind本地socket,发起连接connetct ,完成tcp三次握手 2.向服务器发起http请求,即post或get动作,http协议请求格式见   http协议规范  3.读http响应,可以判定http 服务器和客户端是否通讯正常,如果失败,  可以根据错误代码判定不成功原因。  http 响应和http 错误代码见http协议部分  4.http响应会返回内容的长度和内容类型,这个信息在在在线业务中是个  非常有用的信息,比如流媒体是边看边下载,如果要计算流媒体长度  只能从http响应读取。 ***************************************************************************************/ #include <fcntl.h> #include <sys/syscall.h> #include <sys/mman.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <sys/types.h> #include <errno.h> #include <stdlib.h> #define SERVER_PORT 5000 #define BUF_MASK 0x1ff #define BUF_SIZE (188*7*64) #define O_DIRECT 0x8000 void usage() {     printf("Usage: http_test_client: -d <srv-ip> -p <srv-port> -f <content-file> [-h -a -v]\n");     printf("options are:\n");     printf(" -d <srv-ip>   # IP address of HTTP Server (e.g. 192.168.1.110)\n");     printf(" -p <srv-port> # Port of HTTP Server (e.g. 5000)\n");     printf(" -f <file>     # url of stream; /data/videos prepended (e.g. portugal.mpg) \n");     printf(" -m            # just leave content in memory, dont write to disk (default: write to file)\n");     printf(" -v            # print periodic stats (default: no)\n");     printf(" -h            # prints http_test_client usage\n");     printf("\n"); } double difftime1(struct timeval *start, struct timeval *stop) { double dt = 1000000.*(stop->tv_sec - start->tv_sec) + (stop->tv_usec - start->tv_usec); return dt; } /* This function creates a TCP connection to server and returns the socket descriptor */ int TcpConnect(char *server, int port, int socket_type) { int sd,rc; struct sockaddr_in localAddr, servAddr; struct h
用户4148957
2022/06/14
3380
测试mktime和localtime_r性能及优化方法
// 编译方法:g++ -g -o x x.cpp或g++ -O2 -o x x.cpp,两种编译方式性能基本相同。 // // 结论: // 1) 环境变量TZ和isdst均不影响localtime_r的性能 // 2) 环境变量TZ严重影响mktime和localtime的性能 // 3) mktime性能不受isdst值的影响,localtime性能与isdst值无关 // *4) 另外需要注意localtime_r为非信号安全函数, // 不能在信号处理过程中调用,否则可能发生死锁等问题 // //
一见
2018/08/07
1.7K0
GPU编程(五): 利用好shared memory
前言 之前在第三章对比过CPU和GPU, 差距非常大. 这一次来看看GPU自身的优化, 主要是shared memory的用法. ---- CPU矩阵转置 矩阵转置不是什么复杂的事情. 用CPU实现是很简单的: #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #define LOG_ #define N 1024 /* 转置 */ void transposeCPU( float in[], float out[]
sean_yang
2019/03/06
1.3K0
GPU编程(五): 利用好shared memory
测试mktime和localtime_r性能及优化方法
// 测试mktime和localtime_r性能及优化方法 // // 编译方法:g++ -g -o x x.cpp或g++ -O2 -o x x.cpp,两种编译方式性能基本相同。 // // 结论: // 1) 环境变量TZ和isdst均不影响localtime_r的性能(第一次调用了除外) // 2) 环境变量TZ严重影响localtime的性能 // 3) 环境变量TZ和isdst均会严重影响mktime的性能 // *4) 注意mktim
一见
2018/08/02
2K0
cuBLAS矩阵乘法性能分析(附代码示例)
矩阵乘法是神经网络中最基础、最重要的一个运算。在用CUDA实现矩阵乘法时,不需要我们手动写,cuBLAS库提供了现成的矩阵乘法算子,例如cublasGemmEx和cublasLtMatmul。其中后者是轻量级版本,API调用更灵活。例如对于整数乘法,cublasLtMatmul支持int8的输入输出,而cublasGemmEx只支持int8输入,int32输出。
godweiyang
2021/09/08
2.6K0
算法:Solutions for the Maximum Subsequence Sum Problem
The maximum subarray problem is the task of finding the contiguous subarray within a one-dimensiona
s1mba
2018/01/03
6050
算法:Solutions for the Maximum Subsequence Sum Problem
【C++】攻克哈希表(unordered_map)
hash_map可以说是我一直欲求不得的宝了,第一次接触我就想拿下它,奈何,网上这种的:《手把手教你实现hash_map》,zzz,还手把手呢,自制hash_map,我们自己不会?我要的是使用教程啊。。
看、未来
2020/08/26
1.8K0
设计模式(4)-序列生成器之单例模式
场景:序列生成器 系统中统一的序列生成程序,整个系统统一一套!那么就用单例模式吧! 首先看看单例模式 1)类持有一个自己的实例,而且还是个静态实例。 2)类的构造函数为私有属性。 3)用以获得实例的方
cloudskyme
2018/03/20
9020
设计模式(4)-序列生成器之单例模式
GPU编程(三): CPU与GPU的矩阵乘法对比
前言 在上一篇的最后, 我提到了一个矩阵乘法, 这次与CPU进行对比, 从中可以很明显GPU在并行计算上的优势. ---- 计时函数 在贴出代码之前, 来看下我常用的计时函数, 可以精确到微秒级. 首先头文件是#include<sys/time.h>. 结构体为: struct timeval{ long tv_sec; /*秒*/ long tv_usec; /*微秒*/ }; 来看下使用的小栗子: struct timeval start, end; double t
sean_yang
2019/01/28
1.7K0
GPU编程(三): CPU与GPU的矩阵乘法对比
select 函数实现 三种拓扑结构 n个客户端的异步通信 (完全图+线性链表+无环图)
顺序的规律就是 第i个 客户端读 其他各个客户端 ,其他的各个客户端 向 i 写 ,i 从 1 到 3.
小爷毛毛_卓寿杰
2019/02/13
7950
select 函数实现 三种拓扑结构  n个客户端的异步通信 (完全图+线性链表+无环图)
cuda教程[新手入门学编程]
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说cuda教程[新手入门学编程],希望能够帮助大家进步!!!
Java架构师必看
2022/03/22
3.1K0
cuda教程[新手入门学编程]
嵌入式linux下的c语言简易日志log模块,带颜色显示(一)
Log(DEBUG,"this is debug\n"); Log(INFO,"this is info\n"); Log(ERROR,"this is error\n"); Log(WARN,"this is warn\n");
杨永贞
2020/08/04
2.7K0
Linux C++ 实现一个简易版的ping (也就是ICMP协议)
又不想用ping命令,因为在代码里调用system("ping"); 可能会比较耗时,得单开线程。于是找了个实现ICMP协议的代码。
xcywt
2022/05/09
2.1K0
Linux  C++  实现一个简易版的ping (也就是ICMP协议)
linux网络编程系列(三)--tcp和udp的基本函数调用过程及如何选择
TCP是TCP/IP体系中面向连接的传输层协议,它提供全双工和可靠交付的服务。它采用许多机制来确保端到端结点之间的可靠数据传输,如采用序列号、确认重传、滑动窗口等。
cpp加油站
2021/04/16
1K0
linux网络编程系列(三)--tcp和udp的基本函数调用过程及如何选择
JavaScript 引擎性能比较之一SpiderMonkey[通俗易懂]
JavaScript 是最常用的前端语言, 在后端也渐渐有所应用, 比如 NodeJS, 在C++应用中嵌入JavaScript 到底性能如何? 就拿最流行的 Mozilla SpiderMonkey
全栈程序员站长
2022/11/07
8200
Linux下网络编程-UDP协议探测在线好友
UDP协议 相对TCP协议来讲属于不可靠协议,UDP协议是广播方式发送数据,没有服务器和客户端的概念。
DS小龙哥
2022/05/11
2.2K0
Linux下网络编程-UDP协议探测在线好友
3.10内核TCP慢启动耗时问题分析——拥塞控制算法
TCP使用多种拥塞控制策略来避免雪崩式拥塞。TCP会为每条连接维护一个“拥塞窗口”来限制可能在端对端间传输的未确认分组总数量。这类似TCP流量控制机制中使用的滑动窗口。TCP在一个连接初始化或超时后使用一种“慢启动”机制来增加拥塞窗口的大小。它的起始值一般为最大分段大小(Maximum segment size,MSS)的两倍,虽然名为“慢启动”,初始值也相当低,但其增长极快:当每个分段得到确认时,拥塞窗口会增加一个MSS,使得在每次往返时间(round-trip time,RTT)内拥塞窗口能高效地双倍增长。
johnazhang
2022/07/21
2.4K0
初探sendfile「建议收藏」
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/134831.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/06
3980
如何给10^7个数据量的磁盘文件排序
第一节、如何给磁盘文件排序 问题描述: 输入:一个最多含有n个不重复的正整数(也就是说可能含有少于n个不重复正整数)的文件,其中每个数都小于等于n,且n=10^7。 输出:得到按从小到大升序排列的包含所有输入的整数的列表。 条件:最多有大约1MB的内存空间可用,但磁盘空间足够。且要求运行时间在5分钟以下,10秒为最佳结果。
bear_fish
2018/09/20
7670
如何给10^7个数据量的磁盘文件排序
推荐阅读
相关推荐
掌握异步日志:解锁日志系统的效率和性能
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档