簡體   English   中英

std :: vector reserve()和push_back()比resize()和數組索引更快,為什么?

[英]std::vector reserve() and push_back() is faster than resize() and array index, why?

我正在對一段代碼進行快速性能測試

void ConvertToFloat( const std::vector< short >& audioBlock, 
                     std::vector< float >& out )
{
    const float rcpShortMax = 1.0f / (float)SHRT_MAX;
    out.resize( audioBlock.size() );
    for( size_t i = 0; i < audioBlock.size(); i++ )
    {
        out[i]  = (float)audioBlock[i] * rcpShortMax;
    }
}

我很高興原來非常天真的實現速度超過1毫秒來處理65536個音頻樣本。

然而,為了好玩,我嘗試了以下

void ConvertToFloat( const std::vector< short >& audioBlock, 
                     std::vector< float >& out )
{
    const float rcpShortMax = 1.0f / (float)SHRT_MAX;
    out.reserve( audioBlock.size() );
    for( size_t i = 0; i < audioBlock.size(); i++ )
    {
        out.push_back( (float)audioBlock[i] * rcpShortMax );
    }
}

現在我完全希望它能提供與原始代碼完全相同的性能。 然而,突然循環現在正在使用900usec(即它比其他實現快100usec)。

誰能解釋為什么這會帶來更好的表現? resize()是否初始化新​​分配的向量,其中reserve只分配但不構造? 這是我唯一能想到的。

PS這是在單核2Ghz AMD炫龍64 ML-37上測試的。

resize是否初始化新​​分配的向量,其中reserve只分配但不構造?

是。

調整()

修改容器,使其具有正好n個元素,在末尾插入元素或在必要時從末尾刪除元素。 如果插入了任何元素,則它們是t的副本。 如果n > a.size() ,則此表達式等效於a.insert(a.end(), n - size(), t) 如果n < a.size() ,則相當於a.erase(a.begin() + n, a.end())

保留()

如果n小於或等於capacity() ,則此調用無效。 否則,它是分配額外內存的請求。 如果請求成功,則capacity()大於或等於n; 否則, capacity()不變。 在任何一種情況下, size()都保持不變。

如果向量中插入了多個capacity() - size()元素,則會自動重新分配內存。 重新分配不會更改size() ,也不會更改向量的任何元素的值。 但它確實增加了capacity()

保留會導致手動重新分配。 使用reserve()主要原因是效率:如果您知道向量必須最終增長的容量,那么一次分配該內存通常更有效,而不是依賴於自動重新分配方案。

第一個代碼寫入out[i] ,其歸結為begin() + i (即添加)。 第二個代碼使用push_back ,它可能立即寫入一個等同於end()的已知指針(即沒有添加)。 您可以通過使用迭代器而不是整數索引來使第一次運行與第二次運行一樣快。

編輯:也澄清一些其他的注釋:向量包含浮點數,構造一個浮點數實際上是一個無操作(同樣的方式聲明“浮點數f;”不發出代碼,只告訴編譯器為浮點數節省空間堆棧)。 所以我認為浮點數向量的resize()reserve()之間的任何性能差異都與構造無關。

out.resize( audioBlock.size() );

由於out的大小(= 0)小於audioBlock.size() ,因此會創建其他元素並將其附加到out的末尾。 這通過調用它們的默認構造函數來創建新元素。

保留僅分配內存。

暫無
暫無

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

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