2013-04-11 55 views
0

因此,我在指針方面遇到了一些問題,並找出如何有效地使用它們。指定副本指針

說我有在那裏我從堆棧中像這樣while循環突然離開「節點」對象的情況下。

while(...) { 
    Node obj = stack.top(); 
    stack.pop(); 
    //do something with the obj 
} 

我想有它運行有效,我不應該創建一個新的節點上每次循環。所以我想這可能是更明智的初始化循環外的節點指針:

Node* obj; 
while(...) { 
    obj = &stack.top(); 
    stack.pop(); 
    //do something with the obj 
} 

然而,當我這樣做obj的獲取與由於其參考彈出刪除...

難道是更有效地創建一個副本,並有指針指向複製或只創建每個迭代都有一個新的節點。告訴我,如果我的思維過程與我的基礎一樣,我只是想了解有效的方法來實現這一目標。

編輯:這是我測試Dijkstra算法的一部分,在這裏我通過很多節點搜索並且運行速度很慢,所以我試圖儘可能減少運行時間。

+0

無法猜測創建新節點的相對費用與每次都複製一個現有的 - 特別是因爲你沒有向我們展示任何有關Node的內容,所以我們沒有任何猜測的基礎。 – 2013-04-11 03:23:07

回答

1

這實際上取決於它是多麼昂貴的複製Node。在您的第一個示例中,您已經制作了top()的副本。這樣做通常很好。

但是,如果你發現它昂貴複製Node S(也許通過一些剖析),你可以採用類似shared_ptr這樣就可以取得所有權,一旦你做top(),以及隨後pop()不僅使stack刪除它的所有權Node。那麼你只會初始化shared_ptr這應該是相當便宜,如果你有證據表明Node副本是你的速度問題的來源。

如果Node已經分配了成員數據,並且您有一個拷貝構造函數來複制這些分配的數據,那麼需要考慮的另一件事是您可以創建一個函數,而不是複製數據,而只是將指針該數據,考慮到你將立即刪除Node。在這種情況下複製分配的內存是沒有意義的。

通過首先運行profiler可能會更有意義,以確定導致程序運行速度下降的原因,它可能只是隨着輸入大小縮放而自然減慢,受限於算法實現本身。如果您不確定這是速度慢的原因,那麼優化應用程序的這一特定方面可能不值得花費精力和麻煩。

+0

偉大的信息!真的很感激它。相當缺乏經驗,所以我甚至不知道探查者是什麼。剛剛通過它,41%的用法來自我的C++ stl優先級隊列的推送操作。 「minHeap.push(* currentAdjNode)」。 – 2013-04-11 03:47:37

+0

當然沒問題,很高興我能幫上忙。也許你會想創建一個單獨的問題來解決這個問題,詳細說明你的'Node'的實現(或多或少),以瞭解它爲什麼會在那裏成爲瓶頸。 – 2013-04-11 03:53:05

2

複製和創建指向副本的指針與您的第一個示例大致相同。修復你的第二個例子:

Node* obj; 
while(...) { 
    obj = &stack.top(); 
    // do something with the obj 
    stack.pop(); // do this after processing 
} 

此外,大多數人會認爲這是一個微型優化。除非你的課程是巨大的,你已經確定這個特定的片段是一個瓶頸,你可能會更好,不用擔心它。

+0

當然,當你可以直接使用引用或更好的'stack.top()'的時候,指針是很愚蠢的。 – Pubby 2013-04-11 03:21:25

+0

是的。它將全部編譯成相同的東西無論如何 – Wug 2013-04-11 03:21:59