1 std::vector<int> vecint; 2 std::deque<int> queint; 3 clock_t t0, t1; 4 5 int size = 1000000; 6 7 t0 = clock(); 8 for (int i = 0; i < size; ++i) 9 { 10 vecint.push_back(i); 11 } 12 t1 = clock(); 13 //vector的push_back速度,共350ms,畢竟有realloc和copy的過程 14 std::wcout<<t1 - t0<<std::endl; 15 16 t0 = clock(); 17 for (int i = 0; i < size; ++i) 18 { 19 queint.push_back(i); 20 } 21 t1 = clock(); 22 //而deque因為沒有realloc和copy的過程,只用了340ms,其實也沒快多少 23 //不過要是push_front,就會快非常多了 24 std::wcout<<t1 - t0<<std::endl; 25 26 int i; 27 28 t0 = clock(); 29 for (auto it = vecint.begin(); it != vecint.end(); ++it) 30 { 31 i = *it; 32 } 33 t1 = clock(); 34 //用iterator遍歷vector,花費882ms,不推薦這么遍歷 35 std::wcout<<t1 - t0<<std::endl; 36 37 t0 = clock(); 38 for (auto it = queint.begin(); it != queint.end(); ++it) 39 { 40 i = *it; 41 } 42 t1 = clock(); 43 //用iterator遍歷deque,花費768ms,對於deque這已經是最快的方法了 44 std::wcout<<t1 - t0<<std::endl; 45 46 t0 = clock(); 47 for (int i = 0; i < size; ++i) 48 { 49 i = vecint[i]; 50 } 51 t1 = clock(); 52 //用下標遍歷vector,花費55ms,推薦的方式 53 std::wcout<<t1 - t0<<std::endl; 54 55 t0 = clock(); 56 for (int i = 0; i < size; ++i) 57 { 58 i = queint[i]; 59 } 60 t1 = clock(); 61 //用下標遍歷deque,花費1548ms,比iterator方式慢了一倍 62 std::wcout<<t1 - t0<<std::endl; 63 64 t0 = clock(); 65 for (unsigned int i = 0; i < vecint.size(); ++i) 66 { 67 i = vecint[i]; 68 } 69 t1 = clock(); 70 //一個小細節,即便使用下標遍歷,最好把size提前取出來, 71 //每次訪問一下還是要犧牲性能的,花費了82ms。 72 std::wcout<<t1 - t0<<std::endl;
而list的push_back性能和遍歷性能跟它們就更沒有可比性了。
以上數據引自 http://gfdice.iteye.com/blog/1313520 ,為在VS2010中,使用Dinkumware STL測試的數據。
我的自測數據(1000000條):
#include <vector> #include <deque> #include <sys/time.h> #include <iostream> using std::vector; using std::deque; using std::cout; using std::endl; //struct timeval { // long tv_sec; /* seconds */ // long tv_usec; /* and microseconds 微秒 */ //}; void tv_sub(struct timeval *out, struct timeval *in) { if ((out->tv_usec -= in->tv_usec) < 0) { --out->tv_sec; out->tv_usec += 1000000; } out->tv_sec -= in->tv_sec; } int main() { static timeval tv_start, tv_stop; int MAXSIZE = 1000000; vector<int*> vec(MAXSIZE, new int(0));
int tt = 0; gettimeofday(&tv_start, NULL); for(vector<int*>::iterator it = vec.begin(); it != vec.end(); ++it) tt = **it; gettimeofday(&tv_stop, NULL); tv_sub(&tv_stop, &tv_start); cout << "iteratror: " << tv_stop.tv_sec * 1000000.0 + tv_stop.tv_usec << endl; gettimeofday(&tv_start, NULL); for (int i = 0; i < MAXSIZE; ++i) tt = *vec[i]; gettimeofday(&tv_stop, NULL); tv_sub(&tv_stop, &tv_start); cout << "operator[]: " << tv_stop.tv_sec * 1000000.0 + tv_stop.tv_usec << endl; deque<int*> deq(MAXSIZE, new int(0)); gettimeofday(&tv_start, NULL); for(deque<int*>::iterator it = deq.begin(); it != deq.end(); ++it) tt = **it; gettimeofday(&tv_stop, NULL); tv_sub(&tv_stop, &tv_start); cout << "deq iteratror: " << tv_stop.tv_sec * 1000000.0 + tv_stop.tv_usec << endl; gettimeofday(&tv_start, NULL); for (int i = 0; i < MAXSIZE; ++i) tt = *deq[i]; gettimeofday(&tv_stop, NULL); tv_sub(&tv_stop, &tv_start); cout << "deq operator[]: " << tv_stop.tv_sec * 1000000.0 + tv_stop.tv_usec << endl; }
vector iterator: 31,718 μs
vector [ ]: 9,515 μs
deque iterator: 37,956 μs
deque [ ]: 132,348 μs
對vector遍歷最佳是用operator[],deque則是用iterator更好。
另,關於多線程網上有人這樣說,覺得在概念上更清晰了:
標准C++里沒有線程這個概念,也不支持多線程
鎖會導致性能低下,實際工作中線程很少需要讀寫同一套數據,線程是用來解決io等待的;多線程能不能提高程序的性能很難說,如果問題本身就具有原子性,不能分割,多線程就沒有意義。
盡量減少線程的使用,盡量減小鎖的粒度。
