std::vector遍历
std::vector是我在标准库中实用最频繁的容器。总结一下在遍历和创建vector时需要注意的一些地方。
在不考虑线程安全问题的前提下,在C++11中有五种遍历方式。
方式一
for (size_t i =0; i < vec.size(); i ++) {
int d = vec[i];
}
方式二
size_t len = vec.size();
for (size_t i =0; i < len; i ++) {
int d = vec[i];
}
方式三
for (auto it = vec.begin(); it != vec.end(); it ++) {
int d = *it;
}
方式四
for (int i:vec) {
int d = i;
}
方式五
for_each(vec.begin(), vec.end(), [](int i){
int d = i;
});
代码很简单,如果不实际测试的话。你能推测出哪种方式效率最高吗?
我在mac下面用xcode测试了这五种遍历方式。
////h文件
void testBianli();
void testBianli1(conststd::vector<int>& vec);
void testBianli2(conststd::vector<int>& vec);
void testBianli3(conststd::vector<int>& vec);
void testBianli4(const std::vector<int>& vec);
void testBianli5(const std::vector<int>& vec);
////end h文件
///cpp文件
void testBianli()
{
size_t counter = 1000000;
std::vector<int> vec(counter);
testBianli1(vec);
testBianli2(vec);
testBianli3(vec);
testBianli4(vec);
testBianli5(vec);
}
void testBianli1(conststd::vector<int>& vec)
{
MEARSURE_DURATION(all);
for (size_t i =0; i < vec.size(); i ++) {
int d = vec[i];
}
}
void testBianli2(conststd::vector<int>& vec)
{
MEARSURE_DURATION(all);
size_t len = vec.size();
for (size_t i =0; i < len; i ++) {
int d = vec[i];
}
}
void testBianli3(conststd::vector<int>& vec)
{
MEARSURE_DURATION(all);
for (auto it = vec.begin(); it != vec.end(); it ++) {
int d = *it;
}
}
void testBianli4(conststd::vector<int>& vec)
{
MEARSURE_DURATION(all);
for (int i:vec) {
int d = i;
}
}
void testBianli5(conststd::vector<int>& vec)
{
MEARSURE_DURATION(all);
for_each(vec.begin(), vec.end(), [](int i){
int d = i;
});
}
其中需要定义一个测试函数运行时间的类和一个宏
#define MEARSURE_DURATION(fun) CFunctionDuration fun(std::string(std::string(__FUNCTION__) +" "+std::string(#fun)).c_str() );
class CFunctionDuration {
public:
CFunctionDuration(const char* funname)
{
m_start_df = clock();
sprintf(m_funname,"%s",funname);
}
~CFunctionDuration()
{
double du = (clock() -m_start_df)*0.001;
if (du >= 0) {
printf("%s running duration:%f(ms) \n",m_funname,du);
}
}
private:
double m_start_df;
char m_funname[256];
};
最后输出结果如下:
testBianli1 all running duration:3.440000(ms)
testBianli2 all running duration:2.854000(ms)
testBianli3 all running duration:11.009000(ms)
testBianli4 all running duration:5.109000(ms)
testBianli5 all running duration:7.637000(ms)
很明显了,第二种方式是最快的。个人觉得原因如下:
第一种方法每次都要调用size()函数去计算vec的长度。通过查看size(),其实现如下:
_LIBCPP_INLINE_VISIBILITY
size_type size() const_NOEXCEPT
{return static_cast<size_type>(this->__end_ -this->__begin_);}
指针地址相减,再来一个强制转换最后得到size()。就这这里稍微费点时间。
第三种方式是最费时间的。使用迭代器it循环,迭代器本身不是内部数据,它的各种操作(比较,偏移,取值操作)都是一系列内联函数操作,暗地里干的事远比看到的复杂。这个迭代器给自己套上伪装,让你可以像使用指针一样利用它去访问对象,但是毕竟中间隔了一层。个人觉得迭代器的实用主要是便于stl中算法的实现,有一种通用的数据类型来访问各种容器中的元素。
第四种方式从形式上看非常简洁,可干活却没有长相利索。这是C++11的新特性。这篇博文中有详细介绍http://www.cnblogs.com/h46incon/archive/2013/06/02/3113737.html.
第五种方式也是c++的新特性。其中包括大受推崇的lambda特性。这种特性是向其它语言学习的结果。在这里也跑的不是最快的。
其实这些运行时间结果的差别也只有在遍历过程中对元素操作的过程很简短的时候才会显现出来。当对每个元素操作花费的时间跟纯粹遍历vector所费时间不是一个数量级时,这些区别就不重要了。另外这个时间在不同设备上运行的时间肯定是不一样的。不同编译器下得到的结果也不一样,但是其相对运行效率还是有参考意义的。
std::vector遍历的更多相关文章
- C++ Arrays, std::array, std::vector 总结
原文来自: https://shendrick.net/Coding%20Tips/2015/03/15/cpparrayvsvector.html @Seth Hendrick Original a ...
- c++转载系列 std::vector模板库用法介绍
来源:http://blog.csdn.net/phoebin/article/details/3864590 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作 ...
- C++ 中的std::vector介绍(转)
vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vec ...
- std::vector介绍
vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vec ...
- std::vector<Channel2*> m_allChannels;容器,以及如何根据channelid的意义
std::vector<Channel2*> m_allChannels;容器,以及如何根据channelid的意义 这个容器保存了所有客户端连接的channel Channel2* Li ...
- std::vector数据复制
std::vector<boost::shared_ptr <ITEM> > srcItemList; // 数据源 std::vector<ITEM> des ...
- 单独删除std::vector <std::vector<string> > 的所有元素
下面为测试代码: 1.创建 std::vector< std::vector<string> > vc2; 2.初始化 std::vector<string> vc ...
- std::vector的分片拷贝和插入
一般我们在用Qt的QByteArrary或者List的时候,会有相应的append的方法,该函数,就是把数据加入末尾.但是std::vector就没有相应的方法.但是我们可以用insert方法来实现: ...
- 使用std::vector优化点云动画显示一例
1. 准备 使用std::vector应该知道几点: (1)内存连续的容器,有点像数组 (2)与std::list相比,插入和删除元素比较慢- 因为数据迁移 (3)添加元素可能会引发内存分配和数据迁移 ...
随机推荐
- fibonacci数列的题目——剑指Offer
https://www.nowcoder.net/practice/c6c7742f5ba7442aada113136ddea0c3?tpId=13&tqId=11160&tPage= ...
- 多个线程对hashmap进行put操作的异常
多个线程对hashmap进行put操作的异常 Exception in thread "Thread-0" java.lang.ClassCastException: java.u ...
- Python实例--C#执行Python脚本,传参
# -*- coding: utf-8 -*- # 第一行的目的,是为了让代码里面,可以有中文注释信息. (否则要运行报错) # 这个 Python 脚本, 用于被 C# 来调用. # 简单测试 He ...
- Lotto(DFS处理)
题目再现 题目内容: 给定N个数字,再从中选定M个数字出来. 将每一种组合内的数字由小到大排列之后, 将全部组合依照字典序排列. 请你找出第X组的第Y个数字. 给定的数字为1~N. 范例1 (N,M, ...
- 为部门整理的mysql_db使用军规
mysql_db使用军规: 1.禁止开发測试人员在IDC环境手工删除和改动数据 2.全部需求通过DB工具系统提交 3.禁止在IDC环境DB进行測试 4.IDC环境提交的sql语句一定要经过非正式环境验 ...
- HDOJ 题目2475 Box(link cut tree去点找祖先)
Box Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- 微软将支持.net开源并跨平台,新特性会体现于VS2015
http://news.microsoft.com/2014/11/12/microsoft-takes-net-open-source-and-cross-platform-adds-new-dev ...
- U4699 鸡蛋
U4699 鸡蛋 0通过 37提交 题目提供者飞翔 标签 难度尚无评定 提交 最新讨论 暂时没有讨论 题目背景 调皮的kkk准备恶搞他的同学兼朋友——你! 题目描述 kkk准备从楼上扔鸡蛋下来砸在lz ...
- Easyui 页面訪问慢解决方式,GZIP站点压缩加速优化
1. 静态资源压缩GZIP是站点压缩加速的一种技术,对于开启后能够加快我们站点的打开速度.原理是经过server压缩,client浏览器高速解压的原理,能够大大降低了站点的流量. 详细代码能够參加je ...
- 重启标志log
01) fatal error : 如下: [ >.()[:swapper/][name:disp_lcm&][DISP]disp_lcm_probe [ >.()[:swappe ...