C++ 传参时传内置类型时用传值(pass by value)方式效率较高
来源:唐磊的个人博客《C++ 传参时传内置类型时用传值(pass
by value)方式效率较高》
在《Effective C++》里提到对内置(C-like)类型在函数传参时pass by value比pass by reference更高效,当用OO的c++自定义类型(存在构造/析构等)pass by reference to const 更好,STL里的迭代器和函数对象是用C指针实现的,因此pass by value更好。至于为什么,下面的代码验证了下。
#include <iostream>
using namespace std;
int f(int i)
{
int r = i + 1;
return r;
}
int g(const int & i)
{
int r = i + 1;
return r;
}
int h(int * p)
{
int r = * p + 1;
return r;
}
int inter(int * &p)
{
int r = * p + 1;
return r;
}
int main()
{
int i = 0x11111111;
f(i);
g(i);
h(&i);
int * x = &i;
r = inter(x);
return 0;
}
用VS 2012 默认Debug配置下生成的汇编代码如下:
4: int f(int i)
5: {
00F343D0 push ebp
00F343D1 mov ebp,esp
00F343D3 sub esp,0CCh
00F343D9 push ebx
00F343DA push esi
00F343DB push edi
00F343DC lea edi,[ebp-0CCh]
00F343E2 mov ecx,33h
00F343E7 mov eax,0CCCCCCCCh
00F343EC rep stos dword ptr es:[edi]
6: int r = i + 1;
00F343EE mov eax,dword ptr [i] //直接将i的值取出来给eax
00F343F1 add eax,1 //eax+1
00F343F4 mov dword ptr [r],eax
7: return r;
00F343F7 mov eax,dword ptr [r]
8: }
00F343FA pop edi
00F343FB pop esi
00F343FC pop ebx
00F343FD mov esp,ebp
00F343FF pop ebp
00F34400 ret
后面的几个函数,只截取了关键代码了。
10: int g(const int &i)
11: {
......
12: int r = i + 1;
00F3449E mov eax,dword ptr [i] // 跟传指针一样,取i的地址到eax
00F344A1 mov ecx,dword ptr [eax] // 将eax的值取出来 放到ecx中
00F344A3 add ecx,1 // ecx值+1
00F344A6 mov dword ptr [r],ecx
13: return r;
00F344A9 mov eax,dword ptr [r]
14: }
......

16: int h(int * p)
17: {
......
18: int r = *p + 1;
00F3453E mov eax,dword ptr [p] // 取p的地址,让到eax中
00F34541 mov ecx,dword ptr [eax] //把eax的值取出来,让到ecx中
00F34543 add ecx,1 //exc的值+1
00F34546 mov dword ptr [r],ecx
19: return r;
00F34549 mov eax,dword ptr [r]
20: }
......
指针跟上面引用一样。
22: int inter(int * &p)
23: {
......
24: int r = *p + 1;
01233DBE mov eax,dword ptr [p] //取传进参数(指针)的地址->eax
01233DC1 mov ecx,dword ptr [eax] //取参数指针的地址-->ecx, (是真正值的地址)
01233DC3 mov edx,dword ptr [ecx] //取ecx的内容->edx
01233DC5 add edx,1 //edx 值+1
01233DC8 mov dword ptr [r],edx
25: return r;
01233DCB mov eax,dword ptr [r]
26: }
......

从汇编代码可以看出,为啥内置类型作为函数参数传递时更高效。
C++ 传参时传内置类型时用传值(pass by value)方式效率较高的更多相关文章
- Go语言的传参和传引用[转]
目录[-] 传参和传引用的问题 传slice不是传引用! 什么叫传引用? 为什么传slice不是传引用? 为什么很多人误以为slice是传引用呢? 传指针和传引用是等价的吗? 所有类型的函数参数都是传 ...
- 上有传参下传json的接口调用
1.优化Myrequest import requests from conf.setting import log class MyRequest(): @staticmethod def post ...
- Vue路由传参及传参后刷新导致参数消失处理
项目功能需要,要从列表页跳转到第三方提供的URL上(这里第三方页面我是通过iframe引入在详情页,目的是点击返回时可以通过keepAlive让列表页不刷新,如果不通过iframe直接跳第三方链接,那 ...
- vue传参子传父
vue子传父用$emit实现 1.文件目录结构 2.parent父组件内容 <template> <div class="wrap"> <div> ...
- cocos2dx 菜单按钮回调方法传参 tag传参
.h文件 void menuCallBack(CCObject* pSender); .cpp CCMenuItemSprite* item = CCMenuItemSprite::create( m ...
- vue.js 传参 href传参 与router-link传参
每天学习一点点 编程PDF电子书免费下载: http://www.shitanlife.com/code 1. <a v-bind:href="'#/appinfo/'+cateApp ...
- vue-router4 |name的作用|query传参|parmas传参|动态路由参数|命名视图|别名alias|前置路由守卫|路由过渡效果|滚动行为
vue-router4 出现 No match found for location with path "/" #### router/index.ts文件 import { c ...
- python函数传参是传值还是传引用?
首先还是应该科普下函数参数传递机制,传值和传引用是什么意思? 函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题.基本的参数传递机制有两种:值传递和引用传 ...
- Postman 串行传参和动态传参详解
Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件 用Postman做接口测试的时候,要把多条用例一起执行,就需要把用例连接起来,一次性执行 目录 串行传参 动态传参 使用 ...
随机推荐
- java实例化对象
摘要:分享牛,分享牛分享,java类加载机制,java实例化对象,java实例化对象机制,java基础. java是如何实例化对象的呢?以及实例化对象的先后顺序是什么?下面我们以测试的方式说明. 1. ...
- Matplotlib Toolkits:地图绘制工具
Matplotlib Toolkits:地图绘制工具 有没有一种可以直接在详细地图(如谷歌地图)上绘制上百万坐标点的工具???谷歌地图坐标点多了也不能绘制了. Basemap (Not distrib ...
- 动手试试Android Studio插件开发
由于业务关系,经常需要写一些表单页面,基本也就是简单的增删改查然后上传,做过几个页面之后就有点想偷懒了,这么低水平重复性的体力劳动,能不能用什么办法自动生成呢,查阅相关资料,发现android stu ...
- Python 2.7的字典实现简化版(C语言)
这是一个能自动调整大小的哈希字典,外部接口实现了下列功能. 1.字典级别: 创建字典 dict_new 归零字典 dict_clear 2.键值级别: 查找 dict_search 强制查找 dict ...
- 我的第一个RootKit,支持XP、Vista、Win7、Win8 RTM 32位
只有写过一个BootKit,才能比较深刻的理解其整个过程与机制,也能加深对Windows系统引导各个过程的熟悉和理解. 我写的这个bootkit,暂时还没想到一个比较好的名字,它 1. 支持xp到w ...
- JAVA面向对象-----面向对象(基础预备知识汇总)
终于整理好了面向对象基础预备知识,但是有点多,所以你们懂的,贴图,较长的代码我还是会排版出来的,我不想把时间浪费在排版上在word里排版一次已经很浪费时间了,所以请谅解. public class C ...
- JBOSS EAP 6 系列四 EJB实现——调用(贯穿始终的模块)
本文主要介绍在JBOSS EAP 6.2(或者JBOSS AS7)中模块是如何贯穿EJB实现的始终.延续上一博文<认识模块的使用>的话题继续聊JBOSS做为模块申明式容器的这一特性在EJB ...
- Effective C++ ——资源管理
条款13:以对象来管理资源 在C++中我们经常会涉及到资源的申请与申请,一般都是由关键字new 和 delete来操作的,两者都是成对存在的,缺一不可,否则会出现意想不到的问题,例如: class I ...
- 开源框架Slidingmenu的基本使用
转载本博客请标明出处:点击打开链接 http://blog.csdn.net/qq_32059827/article/details/52464262 侧滑菜单在开发中经常用到,而Slidi ...
- Cocos2D在新版Swift中常量枚举值引用代码的修改
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道在SpriteBuilder中是无法直接给一个CCB文 ...