對vector與deque插值與遍歷的性能數據


 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等待的;多線程能不能提高程序的性能很難說,如果問題本身就具有原子性,不能分割,多線程就沒有意義。

盡量減少線程的使用,盡量減小鎖的粒度。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM