std vector的幾種遍歷方式比較

2021-06-22 13:38:44 字數 2596 閱讀 5677

std::vector是我在標準庫中實用最頻繁的容器。總結一下在遍歷和建立vector時需要注意的一些地方。

在不考慮執行緒安全問題的前提下,在c++11中有五種遍歷方式。

方式一

for (size_t i =0; i < vec.size(); i ++)

方式二

size_t len = vec.size();

for (size_t i =0; i < len; i ++)

方式三

for (auto it = vec.begin(); it != vec.end(); it ++)

方式四

for (int i:vec)

方式五for_each(vec.begin(), vec.end(), (int i));

**很簡單,如果不實際測試的話。你能推測出哪種方式效率最高嗎?

我在mac下面用xcode測試了這五種遍歷方式。

h檔案void testbianli();

void testbianli1(const

std::vector

& vec);

void testbianli2(const

std::vector

& vec);

void testbianli3(const

std::vector

& vec);

void testbianli4(const

std::vector

& vec);

void testbianli5(const

std::vector

& vec);

end h檔案

///cpp檔案

void testbianli()

void  testbianli1(const

std::vector

& vec)

}void  testbianli2(const

std::vector

& vec)

}void testbianli3(const

std::vector

& vec)

}void testbianli4(const

std::vector

& vec)

}void testbianli5(const

std::vector

& vec));}

其中需要定義乙個測試函式執行時間的類和乙個巨集

#define mearsure_duration(fun) cfunctionduration fun(std::string(std::string(__function__) +" " +std::string(#fun)).c_str() );

class cfunctionduration

~cfunctionduration()

}private:

double m_start_df;

char m_funname[256];

}; 最後輸出結果如下:

testbianli1 all running duration:3.440000(ms)

testbianli2 all running duration:2.854000(ms)

testbianli3 all running duration:11.009000(ms)

testbianli4 all running duration:5.109000(ms)

testbianli5 all running duration:7.637000(ms)

很明顯了,第二種方式是最快的。個人覺得原因如下:

第一種方法每次都要呼叫size()函式去計算vec的長度。通過檢視size(),其實現如下:

_libcpp_inline_visibility

size_type size() const

_noexcept

指標位址相減,再來乙個強制轉換最後得到size()。就這這裡稍微費點時間。

第三種方式是最費時間的。使用迭代器it迴圈,迭代器本身不是內部資料,它的各種操作(比較,偏移,取值操作)都是一系列內聯函式操作,暗地裡幹的事遠比看到的複雜。這個迭代器給自己套上偽裝,讓你可以像使用指標一樣利用它去訪問物件,但是畢竟中間隔了一層。個人覺得迭代器的實用主要是便於stl中演算法的實現,有一種通用的資料型別來訪問各種容器中的元素。

第四種方式從形式上看非常簡潔,可幹活卻沒有長相利索。這是c++11的新特性。這篇博文中有詳細介紹

第五種方式也是c++的新特性。其中包括大受推崇的lambda特性。這種特性是向其它語言學習的結果。在這裡也跑的不是最快的。

其實這些執行時間結果的差別也只有在遍歷過程中對元素操作的過程很簡短的時候才會顯現出來。當對每個元素操作花費的時間跟純粹遍歷vector所費時間不是乙個數量級時,這些區別就不重要了。另外這個時間在不同裝置上執行的時間肯定是不一樣的。不同編譯器下得到的結果也不一樣,但是其相對執行效率還是有參考意義的。

遍歷的幾種方式

es5的話也可以使用foreach,es5具有遍歷陣列功能的還有map filter some every reduce reduceright等,只不過他們的返回結果不一樣。但是使用 foreach 遍歷陣列的話,使用 break 不能中斷迴圈,使用 return 也不能返回到外層函式。使用for...

Container DataItem幾種方式

在繫結資料時經常會用到這個句程式 databinder.eval container.dataitem,x 或者 databinder.eval container,dataitem.x 今天又學到一種,而且微軟也說這種方法的效率要比以上兩種高。datarowview container.datai...

std vector與std list的效率比較

一直想知道std中vector和list的效率哪個高些。於是做了乙個簡單的測試,對std vector和list的push back與遍歷操作的效率進行比較。結果如下 1.push back操作 連續push back操作100000個元素,然後clear 一直重複10000次。vector耗時13...