Zero a pod-struct object
来源:互联网 发布:库里15-16赛季数据统计 编辑:程序博客网 时间:2024/05/01 04:53
有时我们希望要将一个结构对象清零。此时我们常用的方法是调用memset。来看一下代码
#include <cstring>struct pod_struct {#ifdef BIG_POD_STRUCT int a[128];#else int a; int b;#endif};int main(){ pod_struct pod; std::memset(&pod, 0, sizeof(pod));}
BIG_POD_STRUCT的定义在后续中会用到。我们知道,memset其实是有开销的,对于比较小的内存块,使用简单的赋值可能更快。因为memset需要根据目标和源地址计算对齐属性,选择最佳的一种方案进行copy。
pod.a = 0;pod.b = 0;
这里简单地赋值,效率其实更高。我们来简单做一下对比。分别使用memset和赋值的方法,迭代1000, 0000次,计算总时间。
#include <cstring>#include <clock.h>struct pod_struct {#ifdef BIG_POD_STRUCT int a[128];#else int a; int b;#endif};int main(){ using namespace my_util; const int COUNT = 10000000; pod_struct pod; SCOPED_CLOCK_BEGIN() for (int i = 0; i < COUNT; ++i) { std::memset(&pod, 0, sizeof(pod)); } SCOPED_CLOCK_END() SCOPED_CLOCK_BEGIN() for (int i = 0; i < COUNT; ++i) { pod.a = 0; pod.b = 0; } SCOPED_CLOCK_END()}
这里的scoped_clock_*宏只是用来测量时间的,实现使用clock()函数完成的,可以精确到毫秒。测量的结果是
memsetassignmenttime(ms)10931很显然,用赋值的方法所用的cpu时间更短。由此我们想到能不能有什么方法可以根据对象的大小来选择这两种方法呢?其实编译器可以帮我们做这些事情。
使用一个initializer对一个pod对象进行初始化,就可以很简单地把一个对象清零。有时我们会这么把数组进行清零。
int a[100] = {0};
这里,第一个元素初始化为0,剩余元素自动被编译器清零。其实更简单的方法是,连0都不指定,直接使用一个空的初始化列表。标准规定,
If there are fewer initializers in the list than there are members in the aggregate, then each member not
explicitly initialized shall be value-initialized (8.5).
value-initialized对于内建的类型而言,就是zero-initialized,也就是简单地清零。所以,我们可以这么初始化pod_struct
pod_struct pod = {};
使用这个结构,编译器会根据目标对象的大小选择最佳的初始化方法,即使用memset或者赋值。来看一下编译器在BIG_POD_STRUCT打开/关闭情况下生存的汇编代码就一目了然了(VC10)。
; BIG_POD_STRUCT not defined xor eax,eax mov dword ptr [pod],eax mov dword ptr [ebp-8],eax
这里编译器把eax的值赋值给了[pod],也就是pod_struct.a,之后再赋值给了pod_struct.b。再看一下BIG_POD_STRUCT打开后的代码,
; BIG_POD_STRUCT defined push 200h push 0 lea eax,[pod] push eax call @ILT+440(_memset)
这里编译器调用了memset,而由于memset是__cdecl函数,所以参数压栈从右到左。size=200H,value=0,dest=&pod,分别被压栈后调用memset。200H正好是pod_struct的大小。
我测试了一下编译器会将赋值替换为memset实现的阈值,在我的机器上是40个字节,VC就会使用memset对pod_struct进行清零。
- Zero a pod-struct object
- Aggregate POD and initialize struct to 0
- AutoCAD object & entity struct
- python32版本,出现问题“struct.error: argument for 's' must be a bytes object”的解决办法
- Python-struct.error: argument for 's' must be a bytes object
- A Linux Environment Zero Overhead
- typedef struct vs. Object - Benefits
- struct object 结构体分析
- POD
- POD
- POD
- pod
- POD
- pod
- struct aaa a;
- 【c++】sizeof(a struct)
- pod 更新第三方依赖遇到的 object version 问题
- SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
- Netbeans 下 配置C/C++编译环境
- 为控件后台添加属性
- Unix normal command
- 我的第一个程序:Java筛法求质数
- Wince中MFC对话框中添加菜单项的做法 (平台是VS2005)
- Zero a pod-struct object
- 电力载波通讯PLC行业及芯片的分析
- linux网络接口源码的结构(转载)
- 联通VAC WebService接口
- 配置WEB安全
- 随机抽取表中的记录
- Eclipse设置多个调试端口
- quartus 小技巧—— 分线。例如总线data[31..0],引出的分线为data[7..0]。
- ubuntu下SCIM输入法安装