首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过值(移动语义)还是指针返回大型对象?

通过值(移动语义)还是指针返回大型对象?
EN

Stack Overflow用户
提问于 2022-03-31 15:06:55
回答 1查看 134关注 0票数 0

我在SO (特别是this)中读过几篇文章和答案,但它们没有给出我的问题的完整答案。他们倾向于关注特殊情况,在这种情况下,移动语义与复制指针一样快,但情况并不总是如此。

例如,考虑这个类:

代码语言:javascript
运行
复制
struct Big {
 map<string, unsigned> m;
 vector<unsigned> v;
 set<string> s;
};

这一职能:

代码语言:javascript
运行
复制
Big foo();

如果foo按值返回并且无法通过RVO优化副本,编译器将应用移动语义,这意味着三个移动,每个类成员一个。如果班级成员超过3人,我就会有更多的操作。如果foo通过指针(可能是智能指针)返回Big对象,则始终是1操作。

更有趣的是,Big对象具有非本地生命周期:它们在应用程序的持续时间内保存在某些数据结构中。因此,您可能期望Big对象在其生命周期中被多次移动,而在foo返回对象之后很久,3个操作(移动语义)和1个操作(指针)的成本一直在增加性能。

考虑到这些背景信息,这里是我的问题

首先,我想确定我对移动语义性能的理解:在上面的示例中,moving Big object比复制指针慢吗?

2-假设移动语义确实较慢,我会接受通过指针返回Big objects吗?还是有更好的方法来实现速度和良好的API (我认为返回值更好)?

编辑

底线:我喜欢按值返回,因为如果我在API中引入一个指针,它们就会扩散到任何地方。所以我想避开他们。然而,我想确定性能的影响。C++是关于速度的,我不能盲目地接受移动语义,而不理解性能的影响。

EN

回答 1

Stack Overflow用户

发布于 2022-03-31 15:23:39

在应用程序期间保存在某些数据结构中。因此,你可能会期望大物体在它们的生命中被多次移动

我不同意这个结论。大多数数据结构的元素在内存中往往是相当稳定的。异常是无保留的std::vectorstd::string,以及其他基于向量的结构,如平面映射。

如果foo按值返回,并且无法通过

优化副本,则为。

因此,以一种可以通过RVO优化的方式实现foo。最好是在C++17中保证不移动。这是一个快速的,方便的API,所以你应该更喜欢。

1-首先,我想确定我对移动语义性能的理解:在上面的示例中,moving比复制指针慢吗?

这是真的。移动Big比复制指针要慢一些。它们都是绝对意义上的轻量级操作(取决于上下文)。

当您考虑将指针返回到新创建的对象时,您还必须考虑对象的生存期以及它的存储位置。如果您正在考虑动态分配它,并返回一个指向动态对象的指针,那么您必须考虑到,动态分配可能比成员对象的几个移动要昂贵得多。而且,与std::map和其他容器所做的所有分配相比,所有这些可能都是微不足道的,因此,所有这些考虑最终都可能无关紧要。

总结:如果你想知道什么更快,那就测量一下。如果一个实现度量的速度要快得多,那么该实现可能就是更快的实现(取决于您在度量方面的出色程度)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71694935

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档