[英]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
是最快的方法(由於ForwardIterator的std::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.