自己动手理解NRV优化
来源:互联网 发布:广数g72编程实例讲解 编辑:程序博客网 时间:2024/05/17 02:33
自己动手理解NRV优化
2010.6.29
一、NRV的简单理解
NRV是Named Return Value的简称。NRV优化简单的说:有一条语句,A a = f();其中f()是一个函数,函数里边申请了一个A的对象b,然后把对象b返回。在对象返回的时候,一般情况下要调用拷贝函数,把函数f()里边的局部对象b拷贝到函数外部的对象a。但是如果用了NRV优化,那就不必要调用拷贝构造函数,编译器可以这样做,把a的地址传递进函数f(),然后不让f()申请要返回的对象b的空间,用a的地址来代替b的地址,这样当要返回对象b的时候,就不必要拷贝了,因为b就是a,省去了局部变量b,省去了拷贝的过程。
二、动手测试
书上得来终觉浅。动手测试才是王道。
测试代码如下:
测试环境:32位机器,vs2005编译器。
测试部分截图
图 1 debug模式下main()函数
图 2 debug模式下f()函数
图 3 release模式下 main()函数
图 4 release模式下f()函数
三、分析
(1)debug模式
分析图 1和图 2可以发现在调用f()函数时,传进了一个参数,这个参数就是拷贝构造函数的目标对象。而拷贝构造函数的源对象就是在f()函数里边定义的局部对象。
(2)release模式
分析图 3和图 4可以发现在调用f()函数时,通过esi传递了外部对象b的地址,在f()函数里边没有申请局部对象的空间,没调用构造函数(内联了),只是输出"construct",也没调用strcpy函数,而是通过寄存器把"zhangsan"拷贝到esi所指向的地址。release模式做了很大的优化!
(3)总结
可以这样理解:debug模式下,给函数传递外部变量b的地址,函数内先申请一个局部变量a,接着对a操作,最后调用拷贝构造函数把a拷贝到外部变量b,结束返回。release模式下,给函数传递外部变量b的地址,函数内不申请局部变量a的空间,把b作为a的空间,接着对a操作,结束返回。
release模式下,局部变量构造函数的操作还是有的,就是没有申请空间,通过寄存器拷贝字符串"zhangsan"的过程就是在调用构造函数,不过看起来被内联在f()函数里边了。可以在f()函数返回之前,局部变量定义之后增加几行代码,再进行测试。
四、关于测试
1、 如何测试?为了方便测试可以输出一些字符,然后在OD里使用超级字符串查找插件,方便定位。
2、如何知道有没有申请空间?看函数入口处有没有类似于sub esp,XX的指令,在debug模式下会发现f()函数里边有申请局部变量,而release模式下f()函数没有申请局部变量。
3、一般情况下,堆栈的局部变量会采用[ebp-XX]的方式访问,而通过堆栈传递的参数会采用[ebp+XX]的方式访问。另外要注意在函数采用寄存器传递参数,例如:this指针采用ecx寄存器,esi作为外部变量的地址。
相关问题:http://topic.csdn.net/u/20100628/20/d4f1c6bf-69fc-4b7e-b2b6-09a3a46d1ba7.html?seed=808337921&r=66584952#r_66584952
PS:有不对之处请指正。
- 自己动手理解NRV优化
- 自己动手理解NRV优化
- 理解NRV优化
- nrv优化
- nrv优化
- NRV优化
- [C++] NRV优化
- 关于NRV优化
- 编译器的NRV优化
- NRV优化详解
- 关于NRV优化详细分析
- NRV
- NRV优化所带来的困惑
- 快速检验NRV优化测试代码
- 快速检验NRV优化测试代码
- 《函数调用时参数、返回值所做的优化处理+编译器NRV优化》
- NRV RVO
- 关于Named Return Value(NRV)optimization-返回值优化
- 手机定位应用
- 一致代码段和非一致代码段
- .map
- 一致代码段,非一致代码段,特权级,代码间跳转[总结]
- 新版中日交流标准日本语初级第二课之基本课文II
- 自己动手理解NRV优化
- Linux 常用命令 目录的创建和删除
- 手机定位企业管理
- 技术园林
- 中小企业网络营销如何快速实施
- 删除时 提示是否删除
- LAMP网站架构方案分析
- 判断字符串中是否含有汉字, 数字,和字母
- shell之条件测试