簡體   English   中英

向量std :: copy上的push_back

[英]vector push_back over std::copy

我有一個函數,它具有無序設置作為參數。 由於我使用的是openmp,因此我將此無序集轉換為vector。 我使用std :: copy進行此轉換。

//pseudo code
func( std::unorderedset s1)
begin
    vector v1;
    std::copy(s1.begin,s2.end,std::back_inserter(v1.end());
#openmp scope
    for( i = 0 ; i < v1.size(); i++ )
    {
         //accessing v1(i)
    }
end

但是我覺得std :: copy是一項昂貴的操作。 所以我的想法是,如果我創建一個類變量向量,並且在更新集合時不斷填充該向量,則可以完全避免執行此std :: copy操作。 由於向量的push_back操作的時間復雜度被攤銷O(1)。 你有什么建議?

std::back_insert_iterator調用std::vector::push_back ,因此您的提案沒有任何改善。

重要的是, 您知道v1的大小是預先存在的 ,因此請利用該信息並讓std::vector 分配一次其存儲以避免v1.size() == v1.capacity()std::push_back進行重新分配v1.size() == v1.capacity()

做這個:

std::vector<T> v1;
v1.reserve(s1.size());
std::copy(s1.begin(), s2.end(), std::back_inserter(v1));

或這個:

std::vector<T> v1(s1.size());
std::copy(s1.begin(), s2.end(), v1.begin());

或者,按照@CoryKramer的建議,從一個范圍中慣用地構造v1

std::vector<T> v1(s1.begin(), s1.end());

更新:

所有這三個版本都執行s1.size()T的副本。 但是,當在GCC上使用T = int 10^7元素進行測量時,它表明std::vector::reserve是最快的方法(由於ForwardIteratorstd::distance是范圍構造的兩倍) 線性復雜度與std::unordered_set::size具有常量 )。 當處理更少和非常大的對象時,這種差異將減小,但仍然存在。

第二種方法只是比第一種慢一點,因為對元素進行了值初始化。

結論:使用std::vector::reserve

您可以使用以下方法提高性能:

func( std::unorderedset s1)
begin
    vector v1;
    v1.reserve(s1.size()); // HERE
    std::copy(s1.begin,s2.end,std::back_inserter(v1.end());
#openmp scope
    for( i = 0 ; i < v1.size(); i++ )
    {
         //accessing v1(i)
    }
end

但是,復制對象的成本是您必須解決的問題

暫無
暫無

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

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