所以我在使用指针时遇到了一些麻烦,并弄清楚如何有效地使用它们。
假设我有一个案例,我在这样的while循环中从堆栈中弹出“Node”对象。
while(...) {
Node obj = stack.top();
stack.pop();
//do something with the obj
}
我想让它有效运行我不应该在循环的每次迭代中创建一个新的Node ...所以我认为在循环外初始化一个Node指针可能更聪明:
Node* obj;
while(...) {
obj = &stack.top();
stack.pop();
//do something with the obj
}
但是,当我这样做时,obj会被pop删除,因为它是一个引用...
创建副本并使指针指向副本或仅在每次迭代时创建新节点会更有效。告诉我,如果我的思维过程也不在此基础上,我只是想了解现在实现这一目标的有效方法。
编辑:这是我测试Dijkstra算法的一部分,我正在通过MANY节点搜索它并且运行缓慢,所以我试图尽可能地缩短运行时间。
答案 0 :(得分:2)
复制和创建指向副本的指针与第一个示例大致相同。修复你的第二个例子:
Node* obj;
while(...) {
obj = &stack.top();
// do something with the obj
stack.pop(); // do this after processing
}
此外,大多数人会认为这是一种微观优化。除非你的Node
类是巨大的并且你已经将这个特定的片段识别为瓶颈,否则你可能最好不要担心它。
答案 1 :(得分:1)
这实际上取决于复制Node
的成本。在第一个示例中,您已经复制了top()
。通常这样做就好了。
但是,如果您发现复制Node
(或许通过某些分析) 费用昂贵,那么您可以使用shared_ptr
这样的内容,这样您就可以拥有所有权完成top()
之后,后续的pop()
只会stack
删除Node
的所有权。然后你只会初始化shared_ptr
,这应该相当便宜,如果你有证据证明Node
份是速度问题的来源。
如果Node
已经分配了成员数据,并且你有一个拷贝构造函数来复制这个分配的数据,另外要考虑的是你可以创建一个函数,而不是复制数据,你只需要窃取考虑到你将要在之后删除Node
,指向该数据的指针。在那种情况下复制分配的内存是没有意义的。
首先通过探查器运行它可能更有意义,以确定导致程序速度减慢的原因,它可能只是随输入大小缩放而自然减速,受到算法的限制实施本身。如果您不确定这是慢速的来源,那么优化应用程序的这一特定方面可能不值得花费和麻烦。