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等待的;多线程能不能提高程序的性能很难说,如果问题本身就具有原子性,不能分割,多线程就没有意义。
尽量减少线程的使用,尽量减小锁的粒度。