我想知道比较/对比时性能是否有任何差异
A)在堆上分配对象,将指针放在容器中的那些对象上,在代码中的其他位置操作容器
例如:
std::list<SomeObject*> someList;
// Somewhere else in the code
SomeObject* foo = new SomeObject(param1, param2);
someList.push_back(foo);
// Somewhere else in the code
while (itr != someList.end())
{
(*itr)->DoStuff();
//...
}
B)创建一个对象,将其放入容器中,在代码中的其他位置操作该容器
例如:
std::list<SomeObject> someList;
// Somewhere else in the code
SomeObject newObject(param1, param2);
someList.push_back(newObject);
// Somewhere else in the code
while (itr != someList.end())
{
itr->DoStuff();
...
}
假设指针都已正确解除分配且一切正常,我的问题是......
如果存在差异,会产生更好的性能,差异有多大?
答案 0 :(得分:6)
插入对象而不是指向对象的指针会导致性能下降。
std::list
以及其他std容器会复制您存储的参数(对于std::map
,密钥和值都会被复制)。
由于您的someList
是std :: list,因此以下行会复制您的对象:
Foo foo;
someList.push_back(foo); // copy foo object
从列表中检索时,它将再次被复制。因此,与使用以下方式复制指针相比,您正在制作整个对象的副本:
Foo * foo = new Foo();
someList.push_back(foo); // copy of foo*
您可以通过在Foo的构造函数,析构函数,复制构造函数中插入print语句来进行双重检查。
编辑:正如评论中所述,pop_front
不会返回任何内容。您通常会使用front
引用前元素,然后使用pop_front
从列表中删除元素:
Foo * fooB = someList.front(); // copy of foo*
someList.pop_front();
OR
Foo fooB = someList.front(); // front() returns reference to element but if you
someList.pop_front(); // are going to pop it from list you need to keep a
// copy so Foo fooB = someList.front() makes a copy
答案 1 :(得分:3)
与大多数表演问题一样,这没有一个明确的答案。
首先,这取决于你对列表的确切做法。指针可能使更容易进行各种操作(如排序)。那是因为比较指针和交换指针可能比比较/交换SomeObject更快(当然,它取决于SomeObject的实现)。
另一方面,动态内存分配往往比在堆栈上分配更糟糕。因此,假设堆栈中有足够的内存用于所有对象,这是另一件需要考虑的事情。
最后,我个人会推荐我所得到的最好的建议:尝试猜测什么会表现更好是毫无意义的。以最有意义的方式编码(最容易实现/维护)。 如果且仅当* 您稍后发现存在性能问题时,请运行探查器并找出原因。很可能,大多数程序都不需要所有这些优化,这将成为一个没有实际意义的点。
答案 2 :(得分:1)
这取决于您如何使用列表。你只是用东西填充它,并进行查找,或者你是否定期插入和删除数据。没有指针,查找可能会略微加快,而使用指针添加和删除元素会更快。
答案 3 :(得分:0)
对于对象,假设没有任何复制构造函数和=运算符重载,它将成为成员复制(因此新对象创建和成员复制)。因此,使用指针是有效的std :: auto_ptr或boost的智能指针更好,但这超出了这个问题的范围。
如果仍然需要使用引用的对象语法。
答案 4 :(得分:0)
需要考虑的其他一些事项(您已经了解了STL容器的复制语义):
memcpy()
。特别是智能指针可能不适用。我提到的所有事情都是微观优化的考虑因素,我甚至不鼓励考虑它们并与它们一起使用。另一方面:我的许多声明都需要验证,并会产生有趣的测试用例。随意对它们进行基准测试。