f(int& i)与f(int i) [英] f(int& i) vs. f(int i)

查看:151
本文介绍了f(int& i)与f(int i)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以指向一个网站,该网站提供的技术理由通过

值优先于参考传递值,而不是
更改值?实际上它可以是任何内置的小字母。类型(短,布尔等)

解决方案

jeffc写道:

任何人都可以指向我当价值不被改变时,提供按价值传递的技术理由的网站优先于参考传递?实际上它可以是任何内置的小字母。类型
(短,布尔等)




技术原因?我想没有...我的意思是,如果你通过一个小

类型,正如你所说的那样,你要在

堆栈上传递值本身(如果按值传递),或者你传递一个指向它的指针(如果传递给

)参考),两者的大小可能相同(即指针可能是
为32位,整数值可能是相同的大小)。


非技术原因?好吧,如果你通过了值,你肯定无法在例行程序中更改

值,当然,讨论可以更多地涉及非技术性方面(即const等)......


-

gabriel


jeffc写道:

任何人都可以指向一个网站,该网站提供的技术原因通过
值优先于传递参考时值不被更改?实际上它可以是任何内置的小字母。类型(短,布尔等)




让我们看看:


int pass_by_reference(int& a ,int& b)

{

返回a + b;

}

int pass_by_value(int a ,int b)

{

返回a + b;

}

passing_params.o:文件格式elf32 -i386


反汇编.text:


00000000< _Z17pass_by_referenceRiS_>:

0:55推%ebp

1:89 e5 mov%esp,%ebp

3:8b 45 0c mov 0xc(%ebp),%eax

6:8b 00 mov(%eax),%eax

8:8b 55 08 mov 0x8(%ebp),%edx

b:03 02 add(%edx) ,%eax

d:c9离开

e:c3 ret

f:90 nop


00000010< ; _Z13pass_by_valueii>:

10:55 push%ebp

11:89 e5 mov%esp,%ebp

13:8b 45 0c mov 0xc(%ebp),%eax

16:03 45 08加0x8(%ebp),%eax

19:c9离开

1a:c3 ret


您认为哪一个更快?

在寄存器调用约定(SPARC)中尝试传递参数。


_Z17pass_by_referenceRiS_:

ld [%o0],%g1

ld [%o1],%o2

retl

add%g1,%o2,%o0

_Z13pass_by_valueii:

retl

add%o0,%o1,%o0


现在您认为哪一个更快?


真正的答案是 - 这取决于。像这样的简单函数很容易被内联的候选者 - 但是如果这些不可内联

然后传递可以按值存在于寄存器中的东西而不是
通过引用
可以获得性能提升,因为不需要

dereference。此外,它取决于调用者的情况,如果调用者没有寄存器中的值,则可能更少

计算上传递指针而非解除引用

来电者。


然而常见的是 - 指令越少,

代码就越快。正确的做法是对你的代码进行基准测试。在

中,极少数情况会真正发挥作用。


Gianni Mariani写道:

反汇编部分.text:[...]


不要忘了,这里有很多变数,例如

优化编译器,(如你所述)内联,糟糕的编译器和

硬件差异,其中任何一个都不能由源代码控制

。例如,编译器可以在例程开始时仅将指针取消引用一次

,在例程中使用临时值,然后再在
处取消引用指针尽管这样做会对同时访问同一指针的多线程系统造成严重破坏,但我确实可以看到这是由
a编译器编写器试着快速...


然而常见的是 - 指令越少,代码越快。正确的做法是对你的代码进行基准测试。


我会说这是昨天的常识。优化器现在抛出一个

扳手,所以非常紧凑和混淆的代码并不一定能保证快速或高效的执行。


除非你使用旧的编译器,并且你非常熟悉通过哪些源代码指令生成

汇编程序代码,否则最好不要花时间优化你的_algorithms_和让

现代编译器弄清楚要生成哪个汇编代码。

在极少数情况下,这真的会有所作为。



非常非常真实。时间最好花在其他地方的绝大多数时间




-

gabriel


Can anyone point me to a web site that gives technical reasons that pass by
value is preferred over pass by reference when the value is not to be
changed? Actually it could be any built-in "small" type (short, bool, etc.)

解决方案

jeffc wrote:

Can anyone point me to a web site that gives technical reasons that
pass by value is preferred over pass by reference when the value is
not to be changed? Actually it could be any built-in "small" type
(short, bool, etc.)



Technical reasons? I guess there are none... I mean, if you pass a "small
type," as you call it, you are passiing either the value itself on the
stack (if pass by value), or you are passing a pointer to it (if pass by
reference), both of which are probably the same size (ie, a pointer might
be 32 bits, and an integer value might be the same size).

Non-technical reasons? Well, if you pass by value you cannot change the
value within the routine for sure, and of course, the discussion can get
much more involved on the non-technical aspects (ie, const, etc...).

--
gabriel


jeffc wrote:

Can anyone point me to a web site that gives technical reasons that pass by
value is preferred over pass by reference when the value is not to be
changed? Actually it could be any built-in "small" type (short, bool, etc.)



Let''s see:

int pass_by_reference( int & a, int & b )
{
return a + b;
}
int pass_by_value( int a, int b )
{
return a + b;
}
passing_params.o: file format elf32-i386

Disassembly of section .text:

00000000 <_Z17pass_by_referenceRiS_>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 0c mov 0xc(%ebp),%eax
6: 8b 00 mov (%eax),%eax
8: 8b 55 08 mov 0x8(%ebp),%edx
b: 03 02 add (%edx),%eax
d: c9 leave
e: c3 ret
f: 90 nop

00000010 <_Z13pass_by_valueii>:
10: 55 push %ebp
11: 89 e5 mov %esp,%ebp
13: 8b 45 0c mov 0xc(%ebp),%eax
16: 03 45 08 add 0x8(%ebp),%eax
19: c9 leave
1a: c3 ret

Which one do you think is faster ?

Try a passing parameters in registers calling convention (SPARC).

_Z17pass_by_referenceRiS_:
ld [%o0], %g1
ld [%o1], %o2
retl
add %g1, %o2, %o0
_Z13pass_by_valueii:
retl
add %o0, %o1, %o0

Now which one do you think is faster ?

The true answer is - it depends. A simple function like these are
easily candidates for inlining - however if these are not inlineable
then passing somthing that can reside in a register by value rather than
by reference can have performance gains due to not needing to
dereference. Also, it depends on the circumstances of the caller, if
the caller does not have the values in registers it may be less
expensive computationally to pass the pointers instead of dereferencing
in the caller.

The common wisdom however is - the fewer instructions, the faster the
code. The correct thing to do is to though is benchmark your code. In
very few circumstances will this really make a difference.


Gianni Mariani wrote:

Disassembly of section .text: [...]
Don''t forget, though, that there are many variables here, such as
optimizing compilers, (as you mention) inlines, crappy compilers, and
hardware differences, none of which can be controlled by the source code
alone. For example, the compiler may dereference the pointer only once
at the beginning of the routine, use a temp value through the routine,
and then dereference the pointer again at the end to put the value back.
Though doing this would wreak havoc on multi threaded systems that access
the same pointers simultaneously, I can definitely see this being done by
a compiler coder tryin'' to be fast...

The common wisdom however is - the fewer instructions, the faster the
code. The correct thing to do is to though is benchmark your code.
I would say that this is yesterday''s common wisdom. Optimizers throw a
wrench into this nowadays, so very compact and obfuscated code does not
necessarily guarantee fast or efficient execution.

Unless you use an old compiler and you are very familiar with what
assembler code is generated by which source code instructions, you are
better off speding time optimizing your _algorithms_ and letting the
modern compiler figure out which assembler code to generate.
In very few circumstances will this really make a difference.



Very, very true. Time is better spent somewhere else the vast majority
of the time.

--
gabriel


这篇关于f(int&amp; i)与f(int i)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆