是否撥打電話reserve
與否取決於:
- 迭代器類型:用於輸入迭代器的實現不能猜大小
- 庫的質量:它可能並不是專門爲「好」的迭代器
- 性能是否值得可維護性減少
讓我們以3點進行排序。
1)迭代器類型
的assign
方法採用兩個迭代器必須至少符合InputIterator
模型。問題是這個模型代表純粹的來源(比如來自網絡的字節):你可以消耗兩倍的東西。因此,如果給定兩個InputIterator
,則不可能在不提取數據的情況下計算它們之間的距離(除非根本不需要數據,但這不是指定的數據),因此您無法先「預留」 。
這通過std::distance
至少需要來說明。
2)執行
我不認爲該標準強制要求實際爲「更好的」迭代器(其中至少模型ForwardIterator
)認爲assign
實施步行範圍兩倍的質量。在受內存帶寬限制的計算中(想象一下在磁帶上讀取這些信息以及非常緩慢的倒帶時間),這實際上會更加昂貴。
然而,許多實施方式(諸如的libC++,見下文)將專門assign
使得在ForwardIterator
存在它調用std::distance
第一如有必要保留的存儲器的適量。
注意:同樣適用於大規模插入的方式。
3)維護負擔
我想指出的是,儘管可能的增益,你(也許在不知不覺中)在這裏重複的信息。
size_t size = std::distance(begin, end);
if (begin != end) ++begin; // new line
v.reserve(size);
v.assign(begin, end);
看看新行的外觀如何突然讓代碼稍微不正確?並不是說它不會起作用,但是所謂的優化不再那麼正確:現在你保留太多了!
個人而言,我會信任我的標準庫實現來做正確的事情。寫他們的人比我有更多的經驗。
如果真的它是您的應用程序中確定的瓶頸,您可以隨時嘗試。只需編寫一個reserve_and_assign
方法來明確它的作用,並衡量它是否更好。
供參考,在這裏的libC++實現,taken here:
template <class _Tp, class _Allocator>
template <class _InputIterator>
typename enable_if
<
__is_input_iterator <_InputIterator>::value &&
!__is_forward_iterator<_InputIterator>::value,
void
>::type
vector<_Tp, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
{
clear();
for (; __first != __last; ++__first)
push_back(*__first);
}
template <class _Tp, class _Allocator>
template <class _ForwardIterator>
typename enable_if
<
__is_forward_iterator<_ForwardIterator>::value,
void
>::type
vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
{
typename iterator_traits<_ForwardIterator>::difference_type __new_size = _VSTD::distance(__first, __last);
if (static_cast<size_type>(__new_size) <= capacity())
{
_ForwardIterator __mid = __last;
bool __growing = false;
if (static_cast<size_type>(__new_size) > size())
{
__growing = true;
__mid = __first;
_VSTD::advance(__mid, size());
}
pointer __m = _VSTD::copy(__first, __mid, this->__begin_);
if (__growing)
__construct_at_end(__mid, __last);
else
this->__destruct_at_end(__m);
}
else
{
deallocate();
allocate(__recommend(static_cast<size_type>(__new_size)));
__construct_at_end(__first, __last);
}
}
我不知道爲什麼它不會保留正確的內存本身的蝙蝠,使用'的std :: distance'。 – chris