首页 > 解决方案 > 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" });
}

标签: c++performancevector

解决方案


在你做任何事情之前,先分析一下代码并获得一个基准。在您对代码进行更改配置文件并获得基准之后。比较基准。如果你不这样做,你就是在掷骰子。它更快吗?谁知道。

配置文件配置文件。

你有push_back两个主要问题:

  1. vector填满时调整大小,以及
  2. 将对象复制到vector.

push_back根据添加项目的方式,您可以对调整大小成本成本进行许多改进。

例如,战略性地使用reserve来最小化调整大小的数量。如果您知道要添加多少项目,您可以检查capacitysize看看是否值得您花时间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"}
};

推荐阅读