c++ STL数据结构的输出参数与堆栈返回值的效率

yfjy0ee7  于 2023-03-25  发布在  其他
关注(0)|答案(4)|浏览(100)

假设我有函数

std::Vector<Point> calculate() {
   std::Vector<Point> points; //do stuff with points
   return points;
}

以及

void calculate(std::Vector<Point>& points) {
   //do stuff with points
}

所以我的问题是针对在堆栈上初始化的对象,而且都是stl对象,在性能上有什么区别吗,流行的方法是什么
问候

6ioyuze2

6ioyuze21#

将值作为引用参数具有以下属性:
1.不会执行复制、移动或任何其他操作。
1.返回值不能立即被用户丢弃。他们不能只是在你的函数的引用参数或其他东西上塞一个临时值。他们必须声明一个变量,因此他们必须给予它一个在当前作用域中存在的名字。

  1. API * 建议 * 该值是一个输入/输出参数。也就是说,有一个值正在被传递,其中将被读取和写入。如果不是这样,那么使用它代表一个次优的API设计元素。
    返回值具有以下属性:
    1.如果复制省略不可用(可能是由于函数实现的本质、编译器不好,或者返回值没有初始化新值),那么返回值将被 * 移动 *。不复制。移动不是免费的,但通常不会比复制几个指针昂贵得多。不会分配或释放新的对象或内存。
  2. API * 强制 * 值的输出性质。用户无法使用它传入的输出,因为它不传入任何内容。同样,函数也无法读取任何值,因为它不接受任何内容。它是一个输出值,句号;函数生成并返回它。
    1.返回值可以根据用户的判断立即丢弃。显然,如果用户经常这样做,这表明有些地方出错了,但由用户决定是否要保留输出值。C++17 [[nodiscard]]属性可以用于丢弃值绝对不正确的情况。
9o685dep

9o685dep2#

由于副本省略,性能很可能是相同的。
这两种方法所表达的内容是不同的

std::vector<Point> calculate()

返回一个向量(可能基于一些参数)。

void calculate(std::vector<Point>& points)

修改现有的向量(同样,可能基于参数)。

yeotifhr

yeotifhr3#

我的拙见:大的返回值会产生更多的问题而不是解决问题……它们看起来更简单,在调用段中更简洁,但右值引用将被避免。
如果你看看旧的,但设计用于效率软件包,如BLAS和LAPACK,大对象通过引用传递,返回值只是错误标志或双精度(例如BLAS中的ddot)。
缺点是表现力会降低,但这是一个很小的成本,因为像内存分配这样的资源会向上移动。
C++在语法和资源管理方面可以大大简化。传递非常量引用在“美观”和代码长度方面有成本,但它是高效的。

yftpprvb

yftpprvb4#

在google编码惯例中,他们推荐使用返回值而不是输出参数,因为返回值可以提高可读性,并且通常可以提供相同或更好的性能。
为了可读性,我认为这是显而易见的。对于输出参数,你必须查看所有参数并确定哪些参数用于输出参数。
对于性能,Scot Meyer在他的书中说“尽可能使用const”。我们不能使用const作为输出参数。此外,现代编译器使用返回值优化(RVO)或命名返回值优化(NRVO)来优化复制操作。
有关更多详细信息,请阅读附加链接:https://google.github.io/styleguide/cppguide.html#Inputs_and_Outputs

相关问题