c++ - c ++ - 迭代std :: vector的最有效方法是什么?为什么?

  显示原文与译文双语对照的内容

在空间时间复杂度方面,以下是迭代 std::vector的最佳方法,为什么?

收费方式为:


for(std::vector<T>::iterator it = v.begin(); it!= v.end(); ++it) {


/* std::cout <<*it;.. . */


}



收费方式为:


for(std::vector<int>::size_type i = 0; i!= v.size(); i++) {


/* std::cout <<v[i];.. . */


}



收费方式为:


for(size_t i = 0; i!= v.size(); i++) {


/* std::cout <<v[i];.. . */


}



收费方式为:


for(auto const& value: a) {


/* std::cout <<value;.. . */



时间:

首先,几乎所有标准库实现中的收费方式为和收费方式 3 。

此外,你所张贴的选项几乎相同。 唯一显著的区别是,以收费方式 1和收费方式 2/3,你依赖编译器优化对 v.end()的调用,并将它的设置为 v.size() 。 如果假设正确,则循环之间没有性能差异。

如果不是,收费 4 是最有效的。 回想一个基于循环的范围扩展到


{


 auto && __range = range_expression ;


 auto __begin = begin_expr ;


 auto __end = end_expr ;


 for ( ; __begin!= __end; ++__begin) {


 range_declaration = *__begin;


 loop_statement


 }


}



这里的重要部分是保证 end_expr 只被评估一次。 还要注意,对于基于循环的范围是最有效的迭代,你不必改变如何处理迭代器的解释。


for (auto value: a) {/*.. . */}



这会将向量的每个元素复制到循环变量 value 中,这可能要比 for (const auto& value : a) ,取决于向量中元素的大小。

注意,在C++17中使用并行算法工具时,还可以尝试


#include <algorithm>


#include <execution>



std::for_each(std::par_unseq, a.cbegin(), a.cend(),


 [](const auto& e) {/* do stuff... */});



但是这是否比普通循环要快取决于可能的详细细节。

添加到 lubgr的答案:

除非你发现proviling的代码是瓶颈,否则效率( 你可能是指'有效的') 不应该是你的第一个关注。 更重要的是代码的可读性和可维护性 ! 因此,你应该选择读取最好的循环变量,通常是 4.

如果你的步骤大于 1 ( whyever你需要。),则索引可能是有用的:


for(size_t i = 0; i <v.size(); i += 2) {.. . }



当每个传感器的+= 2 都是合法的时候,如果向量有大小,则在循环结束时风险。 ( 通常说明:如果大小不等于 0和 m*n-1,则获得。) 所以需要额外的代码。

...