c++中range-based for 的性能分析

這要是對以下幾種在c++裏的 for-range-loop做一個總結

  1. for(auto e : container)
  2. for(auto &e : container)
  3. for(const auto &e : container)
  4. for(auto && e : container)

這裏主要是參考 ref [1] stackoverflow裏的類容,他總結的很好,我這裏做個備份

核心思想是

和函數的參數一樣,Same consideration applies as for function arguments

簡單解釋

  1. for(auto e : container)
    這會使用一個 copy-constructor函數,構造一個副本,也就是說 e,僅僅是container中的一個copy
    test-code 見ref1
  2. for(const auto & e:container),for(auto &e : container)
    這兩者的區別在於 const 不能在for-loop中更改 e,兩者的開銷(通常意義下,取決於copy-construct的開銷)都會比 1低,
  3. for(auto &&e : container)
    這個語法我也是第一次遇見,主要給一些proxy-iterator使用的,
    例如 vector<bool>STL將其設計爲一個bool一個bit 所以是沒法refrence到它的地址的(cpu按byte尋址),如果用 for(auto & e: container)會出現編譯錯誤
    不過, 這種語法是兼容 for(auto & e:container),並且時間開銷接近(見後文的時間測試)

使用總結

  1. For observing mode,即僅僅是read-only的情況
    1. 通常使用 for(const auto &e:container)
    2. 例外,對於copy-cheap的類型(e.g. int,double,…,value type),for(auto e:container)
  2. For modifying mode,需要再遍歷過程中modify 數據的情況
    1. 通常使用 for(auto & e :container)
    2. 對於 proxy-iterator 採用for(auto && e: container)

這裏不得不感慨 cpp這是最難的語言,例外如此多,一點也不general,一點也不generic…

有沒有更簡單一些的規則呢? 更general一些的,有的

  1. For observing
    for(const auto &e : container)不管它是不是copy-cheap,也不管它是不是value-type,(實際測試中(int,long long,double) 使用auto e仍舊會比const auto &e 慢一些,測試見後文)
  2. For modifying
    for(auto && e: container)就ok 了,因爲這兩者 行爲 (並未看過底層是否等價)等價,並且時間也接近

時間測試

  1. copy-construct 在 vector<string>,every string'length is equal to 100
    1. 測試代碼 github

    2. 測試結果

      auto e : 0.132257s
      
      const auto & e: 0.0180348s
      
      auto && e : 0.0188524s
      
  2. 值類型(int,long long,double) 測試
    1. 測試代碼 github
    2. 測試結果
for-type int(s) long long(s) double(s)
auto e 0.0932 0.0924 0.0933
const auto& e 0.0884 0.0861 0.0875
auto && e 0.0903 0.0872 0.0864

需要注意的是測試代碼僅僅是測試的遍歷,沒有訪問過程,如果考慮訪問尋址的開銷,那麼對於value type based on refrence 可能會開銷更多的時間.

refrence

  1. stackoverflow.What is the correct way of using C++11’s range-based for?
  2. cpprefrence

版權聲明

本作品爲作者原創文章,採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議

作者: taotao

轉載請保留此版權聲明,並註明出處

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章