20170407STL012_STL_容器和算法效率
2017-04-07 12:38
288 查看
效率分析:
1:vector:1:是一个连续的,有序容器
2:在尾部添加元素的效率相对比较快,但是如果需要重新分配内存的时候,就会比较慢:,如果一次分配一个比较大的空间,这样的话效率会有提高。
3:另外,如果在vector的中间或者前面添加元素的话,就会变得非常慢。
2:deque:
1:双端队列,它支持向前和向后添加。
3:list:
1:看起来,整个容器是连续的,但实际上是分开的多个块组合起来的。
2:他的所有元素都是通过指针连接起来的,插入和删除非常快,但是读取比较忙。
4:array:
1:C++11刚才添加进来的一个容器。
2:他是一个数组,他是不会变的。
容器分类:
1:序列容器:1:array:
2:deque:
3:vector:
4:list:
5:forward_list:
2:器容器适配:
1:stack:后进先出。
2:dueue:先进先出。
3:priority_dueue:优先队列。
3:关联容器:
1:set:
2:multi_set:
3:map:
4:multi_map:
4:无序关联容器:
1:unordered_set:
2:unorder_multiset:
3:unordered_map:
4:unordered_multimap:
array效率测试:
1:array声明的时候大小就已经定下来了,他不是new出来的,所以保存在栈里面。2:array声明在全局中,大小会相对大些。
#include <iostream> #include <stack> #include <array> #include <vector> #include <ctime> #include <algorithm> const unsigned int TEXTSIZE = 500000; bool FindIf(int val) { return val > 10000; } std::array<int, TEXTSIZE> ci;//声明的时候就指定了大小,如果这个大小不合适(一般不能过大),那么运行就会报错。 void TestArray() { std::cout << "Array:" << std::endl; std::clock_t tbegin = std::clock();//单位100ns for (int i = 0; i < TEXTSIZE; ++i) { ci[i] = rand(); } std::clock_t tend = std::clock();//单位100ns std::cout << "写入的时间:" << tend - tbegin << std::endl;//写入数据 tbegin = std::clock(); std::sort(ci.begin(), ci.end()); tend = std::clock(); std::cout << "排序的时间:" << tend - tbegin << std::endl;//排序 tbegin = std::clock(); std::count_if(ci.begin(), ci.end(), FindIf);//这是找到第一个就退出。 tend = std::clock(); std::cout << "查找时间:" << tend - tbegin << std::endl;//查找 } void Testvector() { std::cout << "vector:" << std::endl; std::vector<int> vi; std::clock_t tbegin = std::clock();//单位100ns for (int i = 0; i < TEXTSIZE; ++i) { vi.push_back(rand()); } std::clock_t tend = std::clock();//单位100ns std::cout << "写入的时间:" << tend - tbegin << std::endl;//写入数据 tbegin = std::clock(); std::sort(vi.begin(), vi.end()); tend = std::clock(); std::cout << "排序的时间:" << tend - tbegin << std::endl;//排序 tbegin = std::clock(); std::count_if(vi.begin(), vi.end(), FindIf);//这是找到第一个就退出。 tend = std::clock(); std::cout << "查找时间:" << tend - tbegin << std::endl;//查找 } int main() { TestArray(); std::cout << std::endl; Testvector(); return 0; }
3:vector涉及到动态分配。
从上面的测试结果可以看出,vector的写入时间比较长。如果提前把vector的容量扩大,然后用下标符来赋值,那么所用的时间会比较短。
4:list:
1:对list做任何的算法操作都是很慢的,对list的插入操作每次的时间都是一样的,但是对于vector等的插入,单数据量非常大的时候就会变得非常慢,list的优势就体现出来了,所以,一般情况下,我们并不使用list,数据量非常大的时候(插入等操作)才会用。
void Testlist() { std::cout << "list:" << std::endl; std::list<int> li; // vi.resize(TEXTSIZE); // std::cout << vi.capacity() << std::endl; std::clock_t tbegin = std::clock();//单位100ns for (int i = 0; i < TEXTSIZE; ++i) { // vi[i] = rand();//这样会比push_back快6倍左右 li.push_back(rand()); } std::clock_t tend = std::clock();//单位100ns std::cout << "写入的时间:" << tend - tbegin << std::endl;//写入数据 //STL里面list不支持排序,它使用的双向迭代器。 /*tbegin = std::clock(); std::sort(li.begin(), li.end()); tend = std::clock(); std::cout << "排序的时间:" << tend - tbegin << std::endl;//排序*/ tbegin = std::clock(); std::count_if(li.begin(), li.end(), FindIf);//这是找到第一个就退出。 tend = std::clock(); std::cout << "查找时间:" << tend - tbegin << std::endl;//查找 }
2:list的访问时非常慢的。
5:forward_list:前向列表
void Testforwardlist() { std::cout << "forward_list:" << std::endl; std::forward_list<int> fli; // vi.resize(TEXTSIZE); // std::cout << vi.capacity() << std::endl; std::clock_t tbegin = std::clock();//单位100ns for (int i = 0; i < TEXTSIZE; ++i) { // vi[i] = rand();//这样会比push_back快6倍左右 fli.push_front(rand()); } std::clock_t tend = std::clock();//单位100ns std::cout << "写入的时间:" << tend - tbegin << std::endl;//写入数据 //STL里面list不支持排序,它使用的双向迭代器。 /*tbegin = std::clock(); std::sort(li.begin(), li.end()); tend = std::clock(); std::cout << "排序的时间:" << tend - tbegin << std::endl;//排序*/ tbegin = std::clock(); std::count_if(fli.begin(), fli.end(), FindIf);//这是找到第一个就退出。 tend = std::clock(); std::cout << "查找时间:" << tend - tbegin << std::endl;//查找 }
1:不支持push_back,不支持向后插入。
2:车输出的效率比list还低些。
6:deque:队列(序列式容器)
1:排序的效率相当低。
2:在写入的时候,效率相比vector慢,
3:但是可以镶嵌添加也可以向后添加。
7:set:
1:set的插入方法非常慢,但是遍历是非常快的。
void Testset()//关联容器 { std::cout << "set:" << std::endl; std::set<int> fli; std::clock_t tbegin = std::clock();//单位100ns for (int i = 0; i < TEXTSIZE; ++i) { fli.insert(rand()); } std::clock_t tend = std::clock();//单位100ns std::cout << "写入的时间:" << tend - tbegin << std::endl;//写入数据 tbegin = std::clock(); std::count_if(fli.begin(), fli.end(), FindIf);//这是找到第一个就退出。 tend = std::clock(); std::cout << "查找时间:" << tend - tbegin << std::endl;//查找 }
2:他里面是一个二叉树(红黑树),实际上,他在数据插入的时候就已经对数据进行排序了,,遍历里面的++算法与普通的不一样,他的效率非常高。
8:multiset:
1:multiset的效率比set要低一些,插入和遍历都会慢一些。
void Testmultiset()//与set差别不大,但 4000 是map和multimap的差别非常大。 { std::cout << "multiset:" << std::endl; std::multiset<int> fli; std::clock_t tbegin = std::clock();//单位100ns for (int i = 0; i < TEXTSIZE; ++i) { fli.insert(rand()); } std::clock_t tend = std::clock();//单位100ns std::cout << "写入的时间:" << tend - tbegin << std::endl;//写入数据 tbegin = std::clock(); std::count_if(fli.begin(), fli.end(), FindIf);//这是找到第一个就退出。 tend = std::clock(); std::cout << "查找时间:" << tend - tbegin << std::endl;//查找 }
2:multiset用的并不多,但是multimap会用到。
9:map:涉及到键值对,以及pair对象的构造,效率比较低。
void Testmap()//与set差别不大,但是map和multimap的差别非常大。 { std::cout << "map:" << std::endl; std::map<int,int> mp; std::clock_t tbegin = std::clock();//单位100ns for (int i = 0; i < TEXTSIZE; ++i) { mp.insert(std::pair<int,int>(i,rand()));//这个插入会比较慢,因为每次都需要构建一个对象 } std::clock_t tend = std::clock();//单位100ns std::cout << "写入的时间:" << tend - tbegin << std::endl;//写入数据 tbegin = std::clock(); std::count_if(mp.begin(), mp.end(), FindIfmap);//这是找到第一个就退出。 tend = std::clock(); std::cout << "查找时间:" << tend - tbegin << std::endl;//查找 }
10:multimap:效率也会比较低。
void Testmultimap()//与set差别不大,但是map和multimap的差别非常大。 { std::cout << "multimap:" << std::endl; std::multimap<int, int> mp; std::clock_t tbegin = std::clock();//单位100ns for (int i = 0; i < TEXTSIZE; ++i) { mp.insert(std::pair<int, int>(i, rand()));//这个插入会比较慢,因为每次都需要构建一个对象 } std::clock_t tend = std::clock();//单位100ns std::cout << "写入的时间:" << tend - tbegin << std::endl;//写入数据 tbegin = std::clock(); std::count_if(mp.begin(), mp.end(), FindIfmap);//这是找到第一个就退出。 tend = std::clock(); std::cout << "查找时间:" << tend - tbegin << std::endl;//查找 }
11:unordered_set:
1:他的插入速度和查找速度更快。
void Testunorderedset()//关联容器 { std::cout << "unordered_set:" << std::endl; std::unordered_set<int> fli; std::clock_t tbegin = std::clock();//单位100ns for (int i = 0; i < TEXTSIZE; ++i) { fli.insert(rand()); } std::clock_t tend = std::clock();//单位100ns std::cout << "写入的时间:" << tend - tbegin << std::endl;//写入数据 tbegin = std::clock(); std::count_if(fli.begin(), fli.end(), FindIf);//这是找到第一个就退出。 tend = std::clock(); std::cout << "查找时间:" << tend - tbegin << std::endl;//查找 }
12:unordered_multiset:
1:
void TestunorderedMultiset()//关联容器 { std::cout << "unordered_multiset:" << std::endl; std::unordered_multiset<int> fli; std::clock_t tbegin = std::clock();//单位100ns for (int i = 0; i < TEXTSIZE; ++i) { fli.insert(rand()); } std::clock_t tend = std::clock();//单位100ns std::cout << "写入的时间:" << tend - tbegin << std::endl;//写入数据 tbegin = std::clock(); std::count_if(fli.begin(), fli.end(), FindIf);//这是找到第一个就退出。 tend = std::clock(); std::cout << "查找时间:" << tend - tbegin << std::endl;//查找 }
13:unordered_map:
1:
void TestUnorderedmap()//与set差别不大,但是map和multimap的差别非常大。 { std::cout << "underedmap:" << std::endl; std::unordered_map<int, int> mp; std::clock_t tbegin = std::clock();//单位100ns for (int i = 0; i < TEXTSIZE; ++i) { mp.insert(std::pair<int, int>(i, rand()));//这个插入会比较慢,因为每次都需要构建一个对象 } std::clock_t tend = std::clock();//单位100ns std::cout << "写入的时间:" << tend - tbegin << std::endl;//写入数据 tbegin = std::clock(); std::count_if(mp.begin(), mp.end(), FindIfmap);//这是找到第一个就退出。 tend = std::clock(); std::cout << "查找时间:" << tend - tbegin << std::endl;//查找 }
总结:
1:序列式容器里面整体效率最高的是array,然后是vector。其他的对算法来说没有帮助,只是他们的结构相对有一些优点。2:关联容器和无序关联容器是没有push_back方法的,他们只有insert插入、erase擦除等方法。
3:map的下标运算符不是指下标,他是一个key。
4:我们使用的这些方法测出的不一定准,因为这些方法不一定是最优实现,比如二叉树的查找是二分法,就会非常快。
相关文章推荐
- 20170407STL012_STL_容器和算法效率
- 20170407STL012_STL_容器和算法效率
- 20170407STL012_STL_容器和算法效率
- 20170407STL012_STL_容器和算法效率
- 20170407STL012_STL_容器和算法效率
- 20170407STL012_STL_容器和算法效率
- 20170407STL012_STL_容器和算法效率
- 20170407STL012_STL_容器和算法效率
- STL的6大组件:容器、类属算法、迭代器、函数对象、适配器、分配器。
- STL容器的效率比较
- STL中的容器、迭代器与算法
- STL 容器,算法,迭代器 总结
- STL 查找vector容器中的指定对象:find()与find_if()算法
- 常用STL容器及算法举例
- 海量数据处理算法 各种STL容器使用的数据结构剖析
- STL(标准模板库)理论基础,容器,迭代器,算法
- STL之vector,数组线性容器array,list容器,算法find,find_if,bind1st,仿函数
- STL容器和算法的函数表
- C++ STL标准容器插入删除算法的复杂度
- 常用STL容器及算法举例 .