C++ const引用参数优化

标签 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.top));
    }
    BOOL Intersects(int l, int t, int r, int b)
    {
        return Intersects(RectI(l, t, r, b));
    }
};

对于方法Intersects(int, int, int, int),它会立即调用Intersects(const RectI&)。这是否需要一个全新的结构 是在内存中创建、构造然后传递给 Intersects(const RectI&) 还是会因为参数是 const 引用而被优化?

最佳答案

应该被内联和优化,假设构造函数(您忘记向我们展示)很简单并且是内联定义的。但唯一可以确定的方法是查看汇编输出。

我整理了这个测试用例:

#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);   
}

这样编译反汇编:

g++ -O3 test.cpp
objdump -dC a.out

输出包含

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 

您可以看到有四个函数调用(callq 指令)要从输入中读取;其余部分由内联比较组成,没有进一步的函数调用:对 Intersects 的调用和两个构造函数调用都已内联。

您的编译器可能会有所不同。

关于C++ const引用参数优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25617235/

相关文章:

c++ - 从 std::stringstream 传递 std::string 引用作为参数

c++ - 共享指针存储在存储在共享指针中的另一个对象内的智能指针 vector 中(Shareption)

Python,组合,排列无重复

c++ - 在 C++ 中对引用的引用是非法的吗?

c - 如何在C中进行优化。如果我将优化级别设置为none(-0),是否需要 volatile 关键字

optimization - 将 CSV 保存为 .MAT 或二进制文件

rust - rust E0597 : borrowed value does not live lnog enough

c++ - WinApi:CW_USEDEFAULT 与 CW_DEFAULT

c++ - Xcode 编译时 CLion 不编译?

c++ - 数组元素到可变参数模板参数