遍历C ++容器 - 最快的方法是什么?

时间:2014-02-20 20:26:24

标签: c++ iterator const-iterator

vector<int> my_vector(10);

// A
for (size_t i = 0; i < my_vector.size(); i++) {
    // Do stuff with my_vector[i]       
}

//B
for (vector<int>::iterator it = my_vector.begin(); it != my_vector.end(); it++) {
    // Do stuff with (*it)      
}

//C
for (vector<int>::const_iterator it = my_vector.begin(); it != my_vector.end(); it++) {
    // Do stuff with (*it)      
}

请回答以下问题:

1)如果我在循环中做的事情改变了my_vector元素的值,那么使用B比A更有效吗?这里效率=更快的遍历。如果是,为什么?

2)如果没有修改my_vector的元素,那么三个中最快的方法是什么?

2 个答案:

答案 0 :(得分:2)

现代编译器足够智能,可以平等地优化所有三个。您始终可以测量它们或查看生成的装配体。

通用迭代器方法的一个好处是,无论您使用何种容器类型,都可以使用相同的代码进行最佳时间顺序迭代(例如,您可以放入list或{{1而不是set)。这可能对您的情况有用,也可能没用。

如果您的应用程序出现问题而无法满足您的性能要求,并且您已将其描述为您的瓶颈,请首先考虑其他更高级别的算法,然后专注于微观优化这一点。

更重要的问题是:这三个中的哪一个产生最清晰,最易读和最易维护的代码?

答案 1 :(得分:1)

在打字方面,以上都不是答案:

std::for_each(v.begin(), v.end(), func);

其中func是函子,独立函数或lambda函数。

就编译器生成的代码而言 - 95%的时间,3个选项中的任何一个都没有(大部分)差异。稍有不同的是索引版本 - 在未优化的构建中,这可能在每次迭代时调用v.size()。但是,随着优化的开启,它们应该基本相同。在确定性能方面,分析和测试是关键。在您考虑尝试优化事物之前,必须找到真正的瓶颈。如果不对应用程序进行概要分析,您可能会优化一些很少被称为或者不是您的瓶颈的东西。

真正的关键在于编写可读代码 - 并且通常避免使用手写循环来支持适当的算法实现。