一些跟性能有关的STL容器常识
都是VS2010下测试的结果。VS2010尴尬之处在于,C++11的实现基本只是个壳,很多实际的实现根本没做,例如emplace_back这个方法,就是push_back的右值引用版本改个名字,而根本没有实现emplace本来的语义,于是不打算说C++11的事儿了。
?
?
?
std::vector<int> vecint;std::deque<int> queint;clock_t t0, t1;int size = 1000000;t0 = clock();for (int i = 0; i < size; ++i){vecint.push_back(i);}t1 = clock();//vector的push_back速度,共350ms,毕竟有realloc和copy的过程std::wcout<<t1 - t0<<std::endl;t0 = clock();for (int i = 0; i < size; ++i){queint.push_back(i);}t1 = clock();//而deque因为没有realloc和copy的过程,只用了340ms,其实也没快多少//不过要是push_front,就会快非常多了std::wcout<<t1 - t0<<std::endl;int i;t0 = clock();for (auto it = vecint.begin(); it != vecint.end(); ++it){i = *it;}t1 = clock();//用iterator遍历vector,花费882ms,不推荐这么遍历std::wcout<<t1 - t0<<std::endl;t0 = clock();for (auto it = queint.begin(); it != queint.end(); ++it){i = *it;}t1 = clock();//用iterator遍历deque,花费768ms,对于deque这已经是最快的方法了std::wcout<<t1 - t0<<std::endl;t0 = clock();for (int i = 0; i < size; ++i){i = vecint[i];}t1 = clock();//用下标遍历vector,花费55ms,推荐的方式std::wcout<<t1 - t0<<std::endl;t0 = clock();for (int i = 0; i < size; ++i){i = queint[i];}t1 = clock();//用下标遍历deque,花费1548ms,比iterator方式慢了一倍std::wcout<<t1 - t0<<std::endl;t0 = clock();for (unsigned int i = 0; i < vecint.size(); ++i){i = vecint[i];}t1 = clock();//一个小细节,即便使用下标遍历,最好把size提前取出来,//每次访问一下还是要牺牲性能的,花费了82ms。std::wcout<<t1 - t0<<std::endl;?
?
而list的push_back性能和遍历性能跟它们就更没有可比性了。
?
接下来试一下VS2010的unique_ptr的效率。
?
?
t0 = clock();for (int i = 0; i < 1000000; ++i){int* p = new int;delete p;}t1 = clock();std::wcout<<t1 - t0<<std::endl;t0 = clock();for (int i = 0; i < 1000000; ++i){std::unique_ptr<int> p(new int);}t1 = clock();std::wcout<<t1 - t0<<std::endl;t0 = clock();for (int i = 0; i < 1000000; ++i){char* p = new char[20];delete [] p;}t1 = clock();std::wcout<<t1 - t0<<std::endl;t0 = clock();for (int i = 0; i < 1000000; ++i){std::unique_ptr<char> p(new char[20]);}t1 = clock();std::wcout<<t1 - t0<<std::endl;?
?
分别是测试普通的object和object数组的情况,结果分别是470 655 488 645,差不多7:10的效率。
?
?