为什么反向迭代器与 std::reverse 相比如此慢然后迭代?

问题描述

#include <iostream>
#include <vector>
#include <windows.h>

using namespace std;

int v_size = 100000;

void foo1()
{
    vector<int>test(v_size,1);
    auto start = GetTickCount();
    reverse(test.begin(),test.end());
    int h = 0;
    for (auto& i : test)
    {
        i += h;
        ++h;
    }
    reverse(test.begin(),test.end());
    auto end = GetTickCount();
    cout <<"foo1 time consumption: "<< (end - start) << endl;
}
void foo2()
{
    vector<int>test(v_size,1);
    auto start = GetTickCount();
    int h = 0;
    for (auto it = test.rbegin(); it != test.rend(); ++it)
    {
        *it += h;
        ++h;
    }
    auto end = GetTickCount();
    cout << "foo2 time consumption : " << (end - start) << endl;
}


int main()
{
    foo1();
    foo2();
    foo2();
    foo1();
    foo2();
}

结果是:

foo1 time consumption: 0
foo2 time consumption : 156
foo2 time consumption : 156
foo1 time consumption: 0
foo2 time consumption : 171

我注意到两件事:

首先,如果我用普通的 for 循环替换 range for 循环,它会变慢。但是时间消耗还是40ms左右。

其次,反向迭代器太慢了。为什么?

解决方法

基准测试非常困难。 See this talk by Chandler Carruth。 我建议使用一个好的基准测试套件,例如Google Benchmark

您可以使用 Quick Bench 在线运行您的 Google 基准测试。所以只需使用以下代码尝试一下:

#include <benchmark/benchmark.h>
#include <vector>

static constexpr int v_size = 100000;

static void foo1(benchmark::State& state) {
    std::vector<int>test(v_size,1);
    for (auto _ : state) {
        reverse(test.begin(),test.end());
        int h = 0;
        for (auto& i : test) {
            i += h;
            ++h;
        }
        reverse(test.begin(),test.end());
    }
    benchmark::DoNotOptimize(test);
}
BENCHMARK(foo1);

void foo2(benchmark::State& state)
{
    std::vector<int>test(v_size,1);
    for (auto _ : state) {
        int h = 0;
        for (auto it = test.rbegin(); it != test.rend(); ++it) {
            *it += h;
            ++h;
        }
    }
    benchmark::DoNotOptimize(test);
}
BENCHMARK(foo2);

您会发现使用反向迭代器比使用反向迭代器快 3.7 倍(两次)。