相关疑难解决方法(0)

为什么Visual Studio在这种情况下不执行返回值优化(RVO)

我正在回答一个问题并建议为大型类型返回按值,因为我相信编译器会执行返回值优化(RVO).但后来有人向我指出Visual Studio 2013没有在我的代码上执行RVO.

我在这里发现了一个关于Visual Studio无法执行RVO的问题,但在这种情况下,结论似乎是,如果真的很重要Visual Studio将执行RVO.在我的情况下它确实很重要,它对性能产生了重大影响,我已经通过分析结果证实了这一点.这是简化的代码:

#include <vector>
#include <numeric>
#include <iostream>

struct Foo {
  std::vector<double> v;
  Foo(std::vector<double> _v) : v(std::move(_v)) {}
};

Foo getBigFoo() {
  std::vector<double> v(1000000);
  std::iota(v.begin(), v.end(), 0);  // Fill vector with non-trivial data

  return Foo(std::move(v));  // Expecting RVO to happen here.
}

int main() {
  std::cout << "Press any key to start test...";
  std::cin.ignore();

  for (int i = 0; i != 100; ++i) { …
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics rvo c++11 visual-studio-2013

41
推荐指数
1
解决办法
4198
查看次数

从函数返回stl向量的有效方法

这是从Efficient方式返回c ++中的std :: vector的扩展问题

#include <cstdio>
#include <vector>
#include <chrono>

std::vector<int> func1() {
    std::vector<int> v;
    v.reserve(1e6);
    for (int i = 0; i < 1e6; i++) v.emplace_back(i);
    return v;
}

std::vector<int> func2() {
    std::vector<int> v;
    v.reserve(1e6);
    for (int i = 0; i < 1e6; i++) v.emplace_back(i);
    return std::move(v);
}

int main() {
    auto start1 = std::chrono::steady_clock::now();
    std::vector<int> v1 = func1();
    auto end1 = std::chrono::steady_clock::now();
    printf("%d\n", std::chrono::duration_cast<std::chrono::nanoseconds>(end1-start1).count());

    auto start2 = std::chrono::steady_clock::now();
    std::vector<int> v2 = func2();
    auto end2 = std::chrono::steady_clock::now();
    printf("%d\n", …
Run Code Online (Sandbox Code Playgroud)

c++ stl c++11

4
推荐指数
1
解决办法
502
查看次数

如何确保执行 RVO 而不是复制?

在许多情况下,我想创建一个新的数据实例并将其返回给 API 调用方。

我了解到unique_ptr/shared_ptr可用于工厂模式(例如,在 C++ 中使用 unique_ptr 的工厂模式

同时,我了解到在许多编译器中都可以进行返回值优化 (RVO)(例如,在 c++ 中返回 std::vector 的有效方法)。

我更喜欢 RVO 因为它更容易使用没有包装的返回值unique_ptr并且更容易阅读代码,但是,由于不能保证 RVO,所以我不想意外牺牲性能并且必须使用unique_ptr以确保返回值是moved而不是复制。

是否有任何方法可以明确指定要移动的返回值,以便在 RVO 可能的情况下它不会抱怨任何内容,或者如果 RVO 不可能,它将触发一些编译器警告?如果这是可能的,我可以安全地摆脱在这种情况下返回 unique_ptr 的情况。

我使用的是 C++17,需要在 macOS 上支持 Apple Clang 11.0,在 Linux 上支持 g++ 9。

编辑:

我仍在学习 C++ 并且在发布此问题时没有区分 RVO(返回值优化)和 NRVO(命名返回值优化)。在我看来 NRVO 在像工厂方法这样的模式中更常见和有用,例如:

vector<foo> vec;
// populate data into vec
return vec;
Run Code Online (Sandbox Code Playgroud)

我正在寻找类似 a 的东西return std::move_only(returned_value),如果无法移动该值(而不是复制移动),它将给我一个编译器警告。也许我应该重新表述我的问题:如果不能保证 NRVO,为什么“按值返回”仍然是这个问题中的推荐方式(在 c++ 中返回 std::vector 的有效方法),答案不应该是“这取决于”您的功能实现以及您是否可以接受意外的性能成本?

c++ smart-pointers nrvo

4
推荐指数
2
解决办法
577
查看次数