c++ - std::push_back 使用起来相对昂贵吗?
问题描述
我想提高以下代码的性能。执行代码时,哪些方面可能会影响代码的性能?
另外,考虑到可以添加到容器中的对象数量没有限制,可以对“Object”或“addToContainer”进行哪些改进以提高程序的性能?
我想知道 C++ 中的 std::push_back 是否会以任何方式影响代码的性能?特别是如果添加到列表没有限制。
struct Object{
string name;
string description;
};
vector<Object> container;
void addToContainer(Object object) {
container.push_back(object);
}
int main() {
addToContainer({ "Fira", "+5 ATTACK" });
addToContainer({ "Potion", "+10 HP" });
}
解决方案
在你做任何事情之前,先分析一下代码并获得一个基准。在您对代码进行更改配置文件并获得基准之后。比较基准。如果你不这样做,你就是在掷骰子。它更快吗?谁知道。
配置文件配置文件。
你有push_back
两个主要问题:
vector
填满时调整大小,以及- 将对象复制到
vector
.
push_back
根据添加项目的方式,您可以对调整大小成本成本进行许多改进。
例如,战略性地使用reserve
来最小化调整大小的数量。如果您知道要添加多少项目,您可以检查capacity
和size
看看是否值得您花时间reserve
避免多次调整大小。请注意,这需要了解vector
的扩展策略,并且是特定于实现的。一个vector
实现的优化可能是另一个非常糟糕的错误。
您可以使用insert
一次添加多个项目。当然,如果您需要在代码中添加另一个容器以便批量插入,这几乎是无用的。
如果您不知道有多少物品进入,您不妨让它vector
完成它的工作并优化物品的添加方式。
例如
void addToContainer(Object object) // pass by value. Possible copy
{
container.push_back(object); // copy
}
这些副本可能很昂贵。摆脱他们。
void addToContainer(Object && object) //no copy and can still handle temporaries
{
container.push_back(std::move(object)); // moves rather than copies
}
std::string
搬家往往很便宜。
这个变体addToContainer
可以与
addToContainer({ "Fira", "+5 ATTACK" });
addToContainer({ "Potion", "+10 HP" });
并且可能只迁移一个指针和每个string
. 他们是临时的,所以没有人关心它是否会撕裂他们的内脏并扔掉尸体。
至于现有Object
的
Object o{"Pizza pop", "+5 food"};
addToContainer(std::move(o));
如果它们是可消耗的,它们也会被移动。如果它们不是消耗品...
void addToContainer(const Object & object) // no copy
{
container.push_back(object); // copy
}
你有一个重载,很难做到这一点。
把这个扔出去
如果您已经有许多您知道将在列表中的项目,而不是一次全部附加它们,请使用初始化列表:
vector<Object> container{
{"Vorpal Cheese Grater", "Many little pieces"},
{"Holy Hand Grenade", "OMG Damage"}
};
推荐阅读
- javascript - 反应垂直范围滑块总是重置为默认忽略新状态
- javascript - React Router 将 props 传递给由?渲染的组件
- visual-studio - 如何减慢函数的输出?
- android - Kotlin“也”在Android Studio中出现奇怪的警告
- reactjs - 在 React 中,是否可以通过 ref 从异步获取中访问类方法?
- r - 在横截面时间序列数据中寻找指标的简单平均值
- vlang - 命令行解析 lib VLang
- postgresql - PostgreSQL - 查询 JSONB 数据中键的第 N 个实例的值
- ios - 展开的图像视图消失后,滚动视图不滚动
- generics - Rust 中的类型推导,怎么做