• C++笔记编译优化:RVO、NRVO


    C++编译器优化技术:RVO、NRVO和复制省略: https://www.cnblogs.com/kekec/p/11303391.html
    C++中的RVO和NRVO:https://blog.csdn.net/yao_zou/article/details/50759301
    详解RVO与NRVO(区别于网上常见的RVO) https://blog.csdn.net/virtual_func/article/details/48709617
    RVO和NRVO的区别是什么?: https://www.zhihu.com/question/29511959

    RVO和NRVO

    RVO (return value optimization), 返回值优化,简称RVO,是编译器的一项优化技术,它涉及(功能是)消除为保存函数返回值而创建的临时对象。
    NRVO (named return value optimization),NRVO的优化比RVO 的优化更进一步,直接将要初始化的对象替代掉返回的局部对象进行操作。

    #include <stdio.h>
    class Object {
     public:
      Object() { printf("%p construct\n", this); }
    
      Object(const Object& cp) { printf("%p copy construct\n", this); }
      ~Object() { printf("%p destruct\n", this); }
    };
    
    Object getObjRVO() {
      return Object();  // RVO
    }
    
    Object getObjNRVO() {
      Object localObj;
      return localObj;  // NRVO
    }
    
    int main() {
      printf("rvo:\n");
      { auto a = getObjRVO(); }
      printf("nrvo:\n");
      { auto b = getObjNRVO(); }                                                                                           
      return 0;
    }
    // https://www.zhihu.com/question/32237405/answer/55440484
    

    编译:g++ test_rvo.cpp -o test
    执行结果:

    rvo:
    0x7ffe558ff9de construct
    0x7ffe558ff9de destruct
    nrvo:
    0x7ffe558ff9df construct
    0x7ffe558ff9df destruct
    

    增加编译选项 -fno-elide-constructors
    编译:g++ test_rvo.cpp -o test -fno-elide-constructors
    执行结果:

    rvo:
    0x7ffe3197775f construct            // getObj 内部构造临时对象
    0x7ffe3197778e copy construct    // return时,调用复制构造函数构造返回值
    0x7ffd9de82f8f destruct              // 析构getObj内部的临时对象
    0x7ffd9de82fbd copy construct    // main函数内利用Object的拷贝构造函数构造对象a
    0x7ffd9de82fbe destruct             // 析构返回值
    0x7ffd9de82fbd destruct             // 析构对象a
    nrvo:
    0x7ffd9de82f8f construct
    0x7ffd9de82fbf copy construct
    0x7ffd9de82f8f destruct
    0x7ffd9de82fbc copy construct
    0x7ffd9de82fbf destruct
    0x7ffd9de82fbc destruct
    

    -fno-elide-constructors 编译选项释义:

    The C++ standard allows an implementation to omit creating a temporary that is only used to initialize another object of the same type. Specifying this option disables that optimization, and forces G++ to call the copy constructor in all cases.
    C++ 标准允许实现省略创建仅用于初始化相同类型的另一个对象的临时对象。 指定此选项会禁用该优化,并强制 g++ 在所有情况下调用复制构造函数。

    增加转移构造函数

    class Object {
     public:
      Object() { printf("%p construct\n", this); }
      Object(const Object& cp) { printf("%p copy construct\n", this); }
      Object(Object&& cp) { printf("%p move construct\n", this); }                                                         
      ~Object() { printf("%p destruct\n", this); }
    };
    

    编译:g++ test_rvo.cpp -o test -fno-elide-constructors
    执行结果:

    rvo:
    0x7ffd42717a2f construct
    0x7ffd42717a5e move construct
    0x7ffd42717a2f destruct
    0x7ffd42717a5d move construct
    0x7ffd42717a5e destruct
    0x7ffd42717a5d destruct
    nrvo:
    0x7ffd42717a2f construct
    0x7ffd42717a5f move construct
    0x7ffd42717a2f destruct
    0x7ffd42717a5c move construct
    0x7ffd42717a5f destruct
    0x7ffd42717a5c destruct
    

    发现没有再调用拷贝构造函数,而是调用的转移构造函数

    RVO 和std::move对比

    增加getObjNRVOMove方法

    Object getObjNRVOMove() {
      Object localObj;
      return std::move(localObj);  // NRVO
    }
    
    int main() {
      printf("nrvo move:\n");
      { auto b = getObjNRVOMove(); }                                                                                       
      return 0;
    }
    

    编译:g++ test_rvo.cpp -o test
    执行结果:

    nrvo move:
    0x7ffc75a6a0ef construct
    0x7ffc75a6a11d move construct
    0x7ffc75a6a0ef destruct
    0x7ffc75a6a11d destruct
    

    可见RVO/ NRVO和std::move可同时生效

  • 相关阅读:
    巧用boost库实现字符串映射消息处理函数
    Apache Continuum 1.3.6 GA 发布下载
    NetBeans 时事通讯(刊号 # 98 Apr 08, 2010)
    source insight
    vim 树形目录插件NERDTree安装及简单用法 心灵净土 博客频道 CSDN.NET
    Janus: Vim Distribution
    vim中的复制与粘贴 | WangYan BLog
    ctagsrevised
    vi的复制粘贴命令_简简单单_百度空间
    贴个自个用的vimrc zmlovelx(帅得不敢出门 c/c++群31843264) 博客频道 CSDN.NET
  • 原文地址:https://www.cnblogs.com/gnivor/p/15843447.html
Copyright © 2020-2023  润新知