初始化方法与构造函数加分配 - 任何性能差异? (C ++)

时间:2013-07-24 11:08:29

标签: c++ optimization allocation

我一直在编写C ++很长一段时间,所以对于不知道这一点我感到愚蠢但是......

我经常编写对性能敏感的代码,当我这样做时,我会尽量避免堆分配。为此,我经常重新使用预先分配的小对象数组,而不是为每个单独的对象调用new和delete。

在这种情况下,我通常这样做:

class MyClass
{
private:
    int x, y;

public:
    inline void Set(_x, _y) { x = _x; y = _y; }
};

...

MyClass &objectToReuse = someArray[someIndex];

objectToReuse.Set(someXValue, someYValue);

但是我怀疑这个看起来更好看的版本会生成相同的代码:

class MyClass
{
private:
    int x, y;

public:
    inline MyClass(_x, _y) : x(_x), y(_y) {}
};

...

MyClass &objectToReuse = someArray[someIndex];

objectToReuse = MyClass(someXValue, someYValue);

现代C ++编译器会“获取”这个,还是构建一个临时对象然后复制它?

1 个答案:

答案 0 :(得分:1)

是的,一个好的编译器将消除这种情况下的额外开销。

我说"在这种情况下"因为它在很大程度上取决于构造函数(以及赋值运算符 - 它所说的"下面的构造函数/构造,读作"或赋值运算符")。如果构造函数影响(或"可能影响")全局状态,则编译器无法删除构造。影响全局状态将是读取或写入文件,更新全局变量,几乎任何对编译器都不知道" (没有源代码)将导致构造函数/副本消除到"失败"。

当然,如果没有消除构造函数/副本,使用setter的代码可能会更有效。在真实场景中,确切的度量只能通过基准测试来确定,因为在编译优化时,通常很难准确判断一行或多行代码实际上有什么影响 - 有时看起来很简单的东西相当复杂的东西(虽然不那么频繁=最终没有花费太多时间。