C++ C++;常数参考参数优化
我在理解这是如何编译的方面有点困难,我对汇编输出的理解还不足以判断C++ C++;常数参考参数优化,c++,optimization,reference,constants,C++,Optimization,Reference,Constants,我在理解这是如何编译的方面有点困难,我对汇编输出的理解还不足以判断 struct RectI { int left; int top; int right; int bottom; ... BOOL Intersects(const RectI& rc) { return (!(left > rc.right || right < rc.left || top > rc.bottom || bottom < rc
struct RectI {
int left; int top; int right; int bottom;
...
BOOL Intersects(const RectI& rc)
{
return (!(left > rc.right || right < rc.left || top > rc.bottom || bottom < rc.top));
}
BOOL Intersects(int l, int t, int r, int b)
{
return Intersects(RectI(l, t, r, b));
}
};
struct RectI{
int left;int top;int right;int bottom;
...
布尔交叉点(常数矩形和rc)
{
返回(!(左>右| |右<左| |上>下| |下<右上));
}
布尔相交(整数l,整数t,整数r,整数b)
{
返回交点(矩形(l,t,r,b));
}
};
对于方法Intersects(int,int,int,int,int)
,它会立即调用Intersects(const RectI&)
。这是否需要一个全新的结构
在内存中创建,构造并传递给相交(const RectI&),或者由于参数是常量引用,因此会对其进行优化?第二个函数使用RectI构造函数创建一个RectI类型的对象,并将常量引用传递给第一个函数。该对象实际上已创建 希望有帮助 Carles.它应该是内联的和优化的,假设构造函数(您忘了向我们展示)是简单的和内联定义的。但唯一确定的方法是查看程序集输出 我把这个测试用例放在一起:
#include <iostream>
typedef bool BOOL;
struct RectI {
int left; int top; int right; int bottom;
RectI(int l, int t, int r, int b) : left(l), top(t), right(r), bottom(b) {}
BOOL Intersects(const RectI& rc) { return (!(left > rc.left || right < rc.right || top > rc.bottom || bottom < rc.top)); }
BOOL Intersects(int l, int t, int r, int b) { return Intersects(RectI(l, t, r, b)); }
};
int main()
{
// Read from input, to prevent the entire calculation being optimised out
int l,t,r,b;
std::cin >> l >> t >> r >> b;
RectI rt(l,t,r,b);
return rt.Intersects(1,2,3,4);
}
输出包含
00000000004005d0 <main>:
4005d0: 48 83 ec 18 sub $0x18,%rsp
4005d4: bf 40 10 60 00 mov $0x601040,%edi
4005d9: 48 89 e6 mov %rsp,%rsi
4005dc: e8 df ff ff ff callq 4005c0 <std::istream::operator>>(int&)@plt>
4005e1: 48 8d 74 24 04 lea 0x4(%rsp),%rsi
4005e6: 48 89 c7 mov %rax,%rdi
4005e9: e8 d2 ff ff ff callq 4005c0 <std::istream::operator>>(int&)@plt>
4005ee: 48 8d 74 24 08 lea 0x8(%rsp),%rsi
4005f3: 48 89 c7 mov %rax,%rdi
4005f6: e8 c5 ff ff ff callq 4005c0 <std::istream::operator>>(int&)@plt>
4005fb: 48 8d 74 24 0c lea 0xc(%rsp),%rsi
400600: 48 89 c7 mov %rax,%rdi
400603: e8 b8 ff ff ff callq 4005c0 <std::istream::operator>>(int&)@plt>
400608: 31 c0 xor %eax,%eax
40060a: 83 3c 24 01 cmpl $0x1,(%rsp)
40060e: 8b 74 24 0c mov 0xc(%rsp),%esi
400612: 8b 54 24 08 mov 0x8(%rsp),%edx
400616: 8b 4c 24 04 mov 0x4(%rsp),%ecx
40061a: 7e 05 jle 400621 <main+0x51>
40061c: 48 83 c4 18 add $0x18,%rsp
400620: c3 retq
400621: 83 fa 02 cmp $0x2,%edx
400624: 7e f6 jle 40061c <main+0x4c>
400626: 83 f9 04 cmp $0x4,%ecx
400629: 7f f1 jg 40061c <main+0x4c>
40062b: 31 c0 xor %eax,%eax
40062d: 83 ee 01 sub $0x1,%esi
400630: 0f 9f c0 setg %al
400633: eb e7 jmp 40061c <main+0x4c>
400635: 66 66 2e 0f 1f 84 00 data32 nopw %cs:0x0(%rax,%rax,1)
40063c: 00 00 00 00
0000000000 4005D0:
4005d0:48 83 ec 18子$0x18,%rsp
4005d4:bf 40 10 60 00 mov$0x601040,%edi
4005d9:4889E6MOV%rsp%rsi
4005dc:e8 df ff callq 4005c0>(int&)@plt>
4005e1:48 8d 74 24 04 lea 0x4(%rsp),%rsi
4005e6:48 89 c7 mov%rax,%rdi
4005e9:e8 d2 ff ff ff callq 4005c0>(int&@plt>
4005ee:48 8d 74 24 08 lea 0x8(%rsp),%rsi
4005f3:48 89 c7 mov%rax,%rdi
4005f6:e8 c5 ff ff ff callq 4005c0>(int&@plt>
4005fb:48 8d 74 24 0c lea 0xc(%rsp),%rsi
400600:48 89 c7 mov%rax,%rdi
400603:e8 b8 ff ff callq 4005c0>(int&@plt>
400608:31 c0异或%eax,%eax
40060a:83 3c 24 01 cmpl$0x1,(%rsp)
40060e:8b 74 24 0c mov 0xc(%rsp),%esi
400612:8b 54 24 08 mov 0x8(%rsp),%edx
400616:8b 4c 24 04 mov 0x4(%rsp),%ecx
40061a:7e 05 jle 400621
40061c:48 83 c4 18添加$0x18,%rsp
400620:c3 retq
400621:83 fa 02 cmp$0x2,%edx
400624:7e f6 jle 40061c
400626:83 f9 04 cmp$0x4,%ecx
400629:7f f1 jg 40061c
40062b:31 c0异或%eax,%eax
40062d:83 ee 01子$0x1,%esi
400630:0f 9f c0设定值%al
400633:eb e7 jmp 40061c
400635:66 66 2e 0f 1f 84 00数据32 nopw%cs:0x0(%rax,%rax,1)
40063c:00
您可以看到有四个函数调用(调用q指令)要从输入读取;其余部分由内联比较组成,没有进一步的函数调用:对相交的两个调用以及两个构造函数调用都已内联
您的编译器可能会有所不同。它的行为必须像创建了临时文件一样。临时创建是否可以优化取决于其他因素,例如RectI
的构造函数和析构函数是否有副作用。构造函数非常简单,它只是将四个值分配给成员数据,并且也是内联的。const&不会在函数调用期间停止对象创建。您可以通过实现第一个值和第二个值来解决此问题,然后根本不需要临时对象。制作一个供我自己使用的旧应用程序。。。不太关心语言的形式。我只是使用Win32定义来保持一致性,尽管RECT没有提供我需要的接口。
00000000004005d0 <main>:
4005d0: 48 83 ec 18 sub $0x18,%rsp
4005d4: bf 40 10 60 00 mov $0x601040,%edi
4005d9: 48 89 e6 mov %rsp,%rsi
4005dc: e8 df ff ff ff callq 4005c0 <std::istream::operator>>(int&)@plt>
4005e1: 48 8d 74 24 04 lea 0x4(%rsp),%rsi
4005e6: 48 89 c7 mov %rax,%rdi
4005e9: e8 d2 ff ff ff callq 4005c0 <std::istream::operator>>(int&)@plt>
4005ee: 48 8d 74 24 08 lea 0x8(%rsp),%rsi
4005f3: 48 89 c7 mov %rax,%rdi
4005f6: e8 c5 ff ff ff callq 4005c0 <std::istream::operator>>(int&)@plt>
4005fb: 48 8d 74 24 0c lea 0xc(%rsp),%rsi
400600: 48 89 c7 mov %rax,%rdi
400603: e8 b8 ff ff ff callq 4005c0 <std::istream::operator>>(int&)@plt>
400608: 31 c0 xor %eax,%eax
40060a: 83 3c 24 01 cmpl $0x1,(%rsp)
40060e: 8b 74 24 0c mov 0xc(%rsp),%esi
400612: 8b 54 24 08 mov 0x8(%rsp),%edx
400616: 8b 4c 24 04 mov 0x4(%rsp),%ecx
40061a: 7e 05 jle 400621 <main+0x51>
40061c: 48 83 c4 18 add $0x18,%rsp
400620: c3 retq
400621: 83 fa 02 cmp $0x2,%edx
400624: 7e f6 jle 40061c <main+0x4c>
400626: 83 f9 04 cmp $0x4,%ecx
400629: 7f f1 jg 40061c <main+0x4c>
40062b: 31 c0 xor %eax,%eax
40062d: 83 ee 01 sub $0x1,%esi
400630: 0f 9f c0 setg %al
400633: eb e7 jmp 40061c <main+0x4c>
400635: 66 66 2e 0f 1f 84 00 data32 nopw %cs:0x0(%rax,%rax,1)
40063c: 00 00 00 00