假设我有函数
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对象,在性能上有什么区别吗,流行的方法是什么问候
6ioyuze21#
将值作为引用参数具有以下属性:1.不会执行复制、移动或任何其他操作。1.返回值不能立即被用户丢弃。他们不能只是在你的函数的引用参数或其他东西上塞一个临时值。他们必须声明一个变量,因此他们必须给予它一个在当前作用域中存在的名字。
[[nodiscard]]
9o685dep2#
由于副本省略,性能很可能是相同的。这两种方法所表达的内容是不同的
std::vector<Point> calculate()
返回一个向量(可能基于一些参数)。
void calculate(std::vector<Point>& points)
修改现有的向量(同样,可能基于参数)。
yeotifhr3#
我的拙见:大的返回值会产生更多的问题而不是解决问题……它们看起来更简单,在调用段中更简洁,但右值引用将被避免。如果你看看旧的,但设计用于效率软件包,如BLAS和LAPACK,大对象通过引用传递,返回值只是错误标志或双精度(例如BLAS中的ddot)。缺点是表现力会降低,但这是一个很小的成本,因为像内存分配这样的资源会向上移动。C++在语法和资源管理方面可以大大简化。传递非常量引用在“美观”和代码长度方面有成本,但它是高效的。
yftpprvb4#
在google编码惯例中,他们推荐使用返回值而不是输出参数,因为返回值可以提高可读性,并且通常可以提供相同或更好的性能。为了可读性,我认为这是显而易见的。对于输出参数,你必须查看所有参数并确定哪些参数用于输出参数。对于性能,Scot Meyer在他的书中说“尽可能使用const”。我们不能使用const作为输出参数。此外,现代编译器使用返回值优化(RVO)或命名返回值优化(NRVO)来优化复制操作。有关更多详细信息,请阅读附加链接:https://google.github.io/styleguide/cppguide.html#Inputs_and_Outputs
4条答案
按热度按时间6ioyuze21#
将值作为引用参数具有以下属性:
1.不会执行复制、移动或任何其他操作。
1.返回值不能立即被用户丢弃。他们不能只是在你的函数的引用参数或其他东西上塞一个临时值。他们必须声明一个变量,因此他们必须给予它一个在当前作用域中存在的名字。
返回值具有以下属性:
1.如果复制省略不可用(可能是由于函数实现的本质、编译器不好,或者返回值没有初始化新值),那么返回值将被 * 移动 *。不复制。移动不是免费的,但通常不会比复制几个指针昂贵得多。不会分配或释放新的对象或内存。
1.返回值可以根据用户的判断立即丢弃。显然,如果用户经常这样做,这表明有些地方出错了,但由用户决定是否要保留输出值。C++17
[[nodiscard]]
属性可以用于丢弃值绝对不正确的情况。9o685dep2#
由于副本省略,性能很可能是相同的。
这两种方法所表达的内容是不同的
返回一个向量(可能基于一些参数)。
修改现有的向量(同样,可能基于参数)。
yeotifhr3#
我的拙见:大的返回值会产生更多的问题而不是解决问题……它们看起来更简单,在调用段中更简洁,但右值引用将被避免。
如果你看看旧的,但设计用于效率软件包,如BLAS和LAPACK,大对象通过引用传递,返回值只是错误标志或双精度(例如BLAS中的ddot)。
缺点是表现力会降低,但这是一个很小的成本,因为像内存分配这样的资源会向上移动。
C++在语法和资源管理方面可以大大简化。传递非常量引用在“美观”和代码长度方面有成本,但它是高效的。
yftpprvb4#
在google编码惯例中,他们推荐使用返回值而不是输出参数,因为返回值可以提高可读性,并且通常可以提供相同或更好的性能。
为了可读性,我认为这是显而易见的。对于输出参数,你必须查看所有参数并确定哪些参数用于输出参数。
对于性能,Scot Meyer在他的书中说“尽可能使用const”。我们不能使用const作为输出参数。此外,现代编译器使用返回值优化(RVO)或命名返回值优化(NRVO)来优化复制操作。
有关更多详细信息,请阅读附加链接:https://google.github.io/styleguide/cppguide.html#Inputs_and_Outputs