簡體   English   中英

返回矢量元素的副本與返回指向矢量元素的指針

[英]Returning copies of vector elements vs returning pointers to vector elements

我有一個像這樣的對象:

class Node {
    float x, y, z;
    size_t tag;
    bool isFree;
    std::vector<size_t> connections; // Usually ~10-100 in length
};

只是為了讓你了解尺寸。 這些節點對象的列表包含數百萬個實例,我將其稱為std::vector<Node> masterNodes 我在其他地方有一個函數返回這些對象的容器,例如:

std::vector<Node> find_nodes()
{
    std::vector<Node> nodes;
    // copy some elements from masterNodes that meet our conditions
    return nodes;
}

我的問題是返回Node *的向量會更高效嗎,或者我的編譯器是否會對此進行優化以使得像我這樣的對象的增益最小化? 例如

std::vector<Node*> find_nodes()
{
    std::vector<Node*> nodes;
    // point to some elements from masterNodes that meet our conditions
    return nodes;
}

我已經看到一些回復(例如這一個 ),建議副本可能幾乎與返回指針一樣有效,承認返回指向向量元素的指針的危險。

返回Node*的向量會更有效,因為您的nodes是來自masterNodesNode副本的向量,並且您的Node比指針大得多。 沒有返回值優化或移動語義可以幫助您擁有(並返回)副本向量這一事實。

順便說一下,你可以返回一個vector<vector<Node>::iterator>而不是vector<Node*> 它與Node*一樣高效,至少在發布版本中,但通常在調試版本中有一些集成檢查,這可能會有所幫助。

參考地點

實際性能在很大程度上取決於硬件,如果您知道如何使用它,可以獲得很多。

當利用參考局部性時,可以獲得最大的硬件引起的性能增益之一 這意味着在時間和空間上處理非常接近的數據可以更好地利用內置CPU緩存,這比使用主存儲器(RAM)快得多。

這就是為什么復制數據以允許連續的本地訪問可以提高性能。

與此相反的是使用間接 間接是使用引用或指針而不是值本身訪問內存的能力。 這樣可以避免復制事物,但是當硬件必須始終從主存儲器中的不同位置獲取每一位數據時,您無法充分利用CPU緩存。

必須測試性能

基本上,復制大的東西會導致一次性的性能損失,但是如果你將使用數據工作很多,你可以使用參考局部來彌補這一點。

但是,您必須自己測試才能知道什么最適合您。 在您的情況下,復制數據的成本可能會比更好地利用CPU緩存所帶來的性能損失更大。

當您使用std::vector<Node>作為方法返回時,您復制所有數據並且需要時間。 使用std::vector<Node*>允許您只擁有數據地址而不進行重復。 但是,如果使用此選項,則必須小心修改數據,因為在masterNode中進行了修改。

您應該嘗試使用std :: copy_if算法,根據參考:

實際上,如果值類型為TriviallyCopyable ,則std :: copy的實現會避免多個賦值並使用批量復制函數,例如std :: memmove

您可以使您的Node實現符合TriviallyCopyable的要求(使用std :: array,而不是std :: vector進行連接),因此使用std::copy_if應該非常快。

另一方面,復制節點受內存限制,如果你沒有足夠的內存,你可能會出現內存不足的錯誤, 如果你確定你永遠不會返回超過100個節點,那么,你有這個控制

如果你使用指針,應用程序將必須管理內存,這減少了使用的內存量,但可以增加由於內存管理所需的時間。

但是你得到的最佳答案是你的測試兩種選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM