c++ - C++中的循环优化技术

标签 c++ loops optimization vector iterator

为了提高应用程序的性能,我们必须在开发阶段考虑循环优化技术

我想向您展示一些不同的方法来迭代一个简单的 std::vector<uint32_t> v :

  1. 带有索引的未优化循环:

    uint64_t sum = 0;
    for (unsigned int i = 0; i < v.size(); i++)
        sum += v[i];
    
  2. 带有迭代器的未优化循环:

    uint64_t sum = 0;
    std::vector<uint32_t>::const_iterator it;
    for (it = v.begin(); it != v.end(); it++)
        sum += *it;
    
  3. 缓存 std::vector::end迭代器:

    uint64_t sum = 0;
    std::vector<uint32_t>::const_iterator it, end(v.end());
    for (it = v.begin(); it != end; it++)
        sum += *it;
    
  4. 预增量迭代器:

    uint64_t sum = 0;
    std::vector<uint32_t>::const_iterator it, end(v.end());
    for (it = v.begin(); it != end; ++it)
        sum += *it;
    
  5. 基于范围的循环:

    uint64_t sum = 0;
    for (auto const &x : v)
        sum += x;
    

在 C++ 中还有其他构建循环的方法;例如使用 std::for_each , BOOST_FOREACH等等……

在您看来,提高性能的最佳方法是什么?为什么?

此外,在性能关键型应用程序中,解开循环可能很有用:同样,您会建议哪种方法?

最佳答案

没有硬性规定,因为它取决于 执行。如果我几年前采取的措施是 然而,典型的:关于唯一有所作为的东西 正在缓存结束迭代器。修复前或修复后不会 差异,与容器和迭代器类型无关。

当时,我没有衡量索引(因为我在比较 不同类型容器的迭代器,但不是全部 支持索引)。但我猜如果你使用索引, 您还应该缓存 v.size() 的结果。

当然,这些措施是针对一个编译器 (g++) 的 系统,具有特定的硬件。你可以知道的唯一方法 你的环境就是衡量你自己。

请注意:您确定已开启全面优化吗? 我的措施显示 3 和 4 之间没有区别,我怀疑 今天编译器优化得更少。

这里的优化非常重要 函数实际上是内联的。如果他们不是, 后增量确实需要一些额外的复制,并且 通常需要额外的函数调用(到拷贝 迭代器的构造函数)也是如此。一旦功能是 然而,内联,编译器可以很容易地看到这一切都是 一个不必要的,并且(至少当我尝试它时)准确地生成 两种情况下的代码相同。 (我会使用预增量 反正。不是因为它有所不同,而是因为如果你 不要,一些白痴会声称它会,尽管 你的措施。或者也许他们不是白痴,而只是在使用 一个特别愚蠢的编译器。)

说实话,当我测量的时候,我很惊讶 缓存结束迭代器会有所不同,即使对于 vector ,因为之前和之前没有区别 后增量,即使对于映射的反向迭代器也是如此。 毕竟,end() 也是内联的;事实上,每一个 我测试中使用的函数是内联的。

至于展开循环:我可能会这样做:

std::vector<uint32_t>::const_iterator current = v.begin();
std::vector<uint32_t>::const_iterator end = v.end();
switch ( (end - current) % 4 ) {
case 3:
    sum += *current ++;
case 2:
    sum += *current ++;
case 1:
    sum += *current ++;
case 0:
}
while ( current != end ) {
    sum += current[0] + current[1] + current[2] + current[3];
    current += 4;
}

(这是 4 的因数。如果 必要的。)

关于c++ - C++中的循环优化技术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18213565/

相关文章:

c++ - 有没有在不使用CSS的情况下用c++编写的GTK + 3中多行文本字段的示例?

python - 如何将迭代列表的新结果附加到数据框中的新列中

javascript - 反向 while 循环如何知道何时在 JavaScript 中停止?

r - 将最大似然估计的系数放入观星表中

java - `if else` 和 `if-else if-else` 之间有区别吗?

gcc - 禁用 GCC 中特定循环的展开

c++ - 将 cv::Mat 转换为 tesseract

c# - Windows Mobile 中的 Flash SMS

c++ - 我不能得到一个指针作为 STL 谓词的参数吗?

c++ - 查找数组中缺失的数字