实战c++中的vector系列--vector的遍历(stl算法、vector迭代器(不要在循环中推断不等于end())、operator[])
2017-07-26 11:01
639 查看
遍历一个vector容器有非常多种方法。使用起来也是仁者见仁。
通过索引遍历:
迭代器遍历:
算法遍历:
非常多书上推荐的是使用算法进行遍历。
写了一个简单的程序对上面的三种方法进行了比較:
当vector初始化10000个元素时,三种方法的效率不相上下。执行几次时间相差无几:
//输出:
//1718 operator[]
//1735 iterator
//1797 algorithm
可是当把veector初始化100000的时候,三种方法的效率就有了较大的差距:
//输出:
//20016 operator[]
//32172 iterator
//62468 algorithm
再写一个vector里放一个类:
再执行一次,结果为:
//296
//63
//594
//1672
这个时候使用algorithm+functional进行遍历效率最高。
个人认为下标索引的方式总是会效率高于迭代器方式。
以下分析一下两种迭代器方式。为何相差不小呢:
这就要看一下std::vector::end()的原型了:
就是每次推断itr != vAAA.end()的时候,都要进行又一次构造一个迭代器并进行返回。这样当然减少的效率。
通过索引遍历:
for (i = 0; i<v.size(); i++) { cout << v[i] << " "; }
迭代器遍历:
for (vInt::const_iterator iter = v.begin(); iter != v.end();iter++) { cout << *iter << " "; }
算法遍历:
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
非常多书上推荐的是使用算法进行遍历。
写了一个简单的程序对上面的三种方法进行了比較:
#include<iostream>
#include<vector>
#include<iterator>
#include<algorithm>
#include<time.h>
#include<windows.h>
using namespace std;
typedef vector<int> vInt;
void print_vec_operator(const vInt & v)//方法一,採用下标訪问
{
int i;
for (i = 0; i<v.size(); i++) { cout << v[i] << " "; }
cout << endl;
}
void print_vec_iterator(const vInt &v)//方法二,採用迭代器訪问
{
for (vInt::const_iterator iter = v.begin(); iter != v.end();iter++) { cout << *iter << " "; }
cout << endl;
}
void print_vec_algorithm(const vInt &v)//方法三。将容器的内容拷贝到cout绑定的迭代器
{
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
}
int main()
{
vInt v;
int i;
for (i = 0; i<100000; i++)
{
v.push_back(i);
}
int start_time_print_vec1 = GetTickCount();
print_vec_operator(v);
int end_time_print_vec1 = GetTickCount();
int start_time_print_vec2 = GetTickCount();
print_vec_iterator(v);
int end_time_print_vec2 = GetTickCount();
int start_time_print_vec3 = GetTickCount();
print_vec_algorithm(v);
int end_time_print_vec3 = GetTickCount();
std::cout << (end_time_print_vec1 - start_time_print_vec1) << endl;
std::cout << (end_time_print_vec2 - start_time_print_vec2) << endl;
std::cout << (end_time_print_vec3 - start_time_print_vec3) << endl;
return 0;
}
当vector初始化10000个元素时,三种方法的效率不相上下。执行几次时间相差无几:
//输出:
//1718 operator[]
//1735 iterator
//1797 algorithm
可是当把veector初始化100000的时候,三种方法的效率就有了较大的差距:
//输出:
//20016 operator[]
//32172 iterator
//62468 algorithm
再写一个vector里放一个类:
#include<iostream> #include<vector> #include<iterator> #include <algorithm> #include <functional> #include<windows.h> class AAA { public: void MakeFull2() { } }; int main() { int nCount = 1000000; std::vector< AAA* > vAAA; vAAA.resize(nCount); for (int i = 0; i < nCount; ++i) { vAAA[i] = new AAA; } // 时间 int start, end; // 測试成员函数调用(std::vector下标訪问方式) start = GetTickCount(); size_t count = vAAA.size(); for (size_t i = 0; i < count; ++i) vAAA[i]->MakeFull2(); end = GetTickCount(); std::cout << end - start << std::endl; // 測试成员函数调用(STL算法方式) start = GetTickCount(); std::for_each(vAAA.begin(), vAAA.end(), std::mem_fun<void, AAA>(&AAA::MakeFull2)); end = GetTickCount(); std::cout << end - start << std::endl; // 測试成员函数调用(STL迭代器方式) start = GetTickCount(); std::vector< AAA* >::iterator itr_end = vAAA.end(); for (std::vector< AAA* >::iterator itr = vAAA.begin(); itr != itr_end; ++itr) (*itr)->MakeFull2(); end = GetTickCount(); std::cout << end - start << std::endl; // 測试成员函数调用(STL迭代器方式) start = GetTickCount(); for (std::vector< AAA* >::iterator itr = vAAA.begin(); itr != vAAA.end(); ++itr) (*itr)->MakeFull2(); end = GetTickCount(); std::cout << end - start << std::endl; return 0; } //输出: //313 oprator[] //62 algorithm //422 iterator //922 iterator
再执行一次,结果为:
//296
//63
//594
//1672
这个时候使用algorithm+functional进行遍历效率最高。
个人认为下标索引的方式总是会效率高于迭代器方式。
以下分析一下两种迭代器方式。为何相差不小呢:
这就要看一下std::vector::end()的原型了:
iterator end() _NOEXCEPT { // return iterator for end of mutable sequence return (iterator(this->_Mylast(), &this->_Get_data())); }
就是每次推断itr != vAAA.end()的时候,都要进行又一次构造一个迭代器并进行返回。这样当然减少的效率。
相关文章推荐
- 实战c++中的vector系列--vector的遍历(stl算法、vector迭代器(不要在循环中判断不等于end())、operator[])
- 实战c++中的vector系列--vector的遍历(stl算法、vector迭代器(不要在循环中判断不等于end())、operator[])
- 实战c++中的vector系列--vector应用之STL的find、find_if、find_end、find_first_of、find_if_not(C++11)
- 实战c++中的vector系列--vector应用之STL的find、find_if、find_end、find_first_of、find_if_not(C++11)
- 实战c++中的vector系列--对vector<自定义类>使用std::find 和 std::find_if 算法
- 实战c++中的vector系列--构造、operator=和assign区别
- 实战c++中的vector系列--构造、operator=和assign区别
- 实战c++中的vector系列--对vector<自定义类>使用std::find 和 std::find_if 算法
- 实战c++中的vector系列--构造、operator=和assign差别
- 实战c++中的vector系列--对vector<自定义类>使用std::find 和 std::find_if 算法
- 实战c++中的vector系列--使用sort算法对vector进行排序(对vector<string>排序、使用稳定的排序std::stable_sort())
- 实战c++中的vector系列--使用sort算法对vector进行排序(对vector<string>排序、使用稳定的排序std::stable_sort())
- 实战c++中的vector系列--使用sort算法对vector<unique_ptr<string>>进行排序(sort函数出错“应输入 2 个参数,却提供了 3 个)
- 实战c++中的vector系列--使用sort算法对vector<unique_ptr<string>>进行排序(sort函数“应输入 2 个参数,却提供了 3 个)
- 实战c++中的vector系列--vector<unique_ptr<>>作为函数的参数
- 实战c++中的vector系列--正确释放vector的内存(clear(), swap(), shrink_to_fit())
- 实战c++中的vector系列--再谈vector的insert()方法(都是make_move_iterator惹的祸)
- [C++]STL中vector容器 begin()与end()函数、front()与back()的用法
- 实战c++中的vector系列--正确释放vector的内存(clear(), swap(), shrink_to_fit())
- c++ stl容器vector删除(erase),遍历等基本用法介绍及头文件