条件循环:变量与函数?

时间:2019-06-17 19:50:59

标签: c++ loops conditional-statements

是否有任何值得选择的理由,例如性能或安全性?

std::vector<std::string> some_vec{ "a","b","c"};

std::vector<std::string>::const_iterator iter = some_vec.begin();
std::vector<std::string>::const_iterator end = some_vec.end();

while( iter++ != end ){Do}

-

std::vector<std::string> some_vec{ "a","b","c"};

std::vector<std::string>::const_iterator iter = some_vec.begin();

while( iter++ != some_vec.end() ){Do}

2 个答案:

答案 0 :(得分:2)

第一个依赖于end在循环期间不会失效:

// some_vec initialised with data!
std::vector<std::string> some_vec; 

std::vector<std::string>::const_iterator iter = some_vec.begin();
//std::vector<std::string>::const_iterator end = some_vec.end();

while( iter++ != some_vec.end() ){
    if (p(*iter)) iter = some_vec.insert(iter, "foo");
}

insert可能会使所有迭代器无效,因此end不能用于比较。

出于效率考虑,我不会太担心。如果some_vec.end()总是返回相同的迭代器,则希望编译器意识到这一点并执行适当的优化。

答案 1 :(得分:2)

首先,while( iter++ != end ){Do}是错误的。您最终将在循环主体中具有结束迭代器。要解决此问题,我们可以使用quick-bench.com来查看性能是否存在差异:

#include <vector>

static void test0(benchmark::State& state)
{
    std::vector<std::string> some_vec{ "a", "b", "c" };

    for (auto _ : state)
    {
        auto iter = some_vec.cbegin();
        auto end = some_vec.cend();
        while (iter != end)
        {
            auto ch = (*iter++)[0];
            benchmark::DoNotOptimize(ch);
        }
    }
    benchmark::DoNotOptimize(some_vec);
}
// Register the function as a benchmark
BENCHMARK(test0);

static void test1(benchmark::State& state)
{
    // Code before the loop is not measured
    std::vector<std::string> some_vec{ "a", "b", "c" };
    for (auto _ : state)
    {
        auto iter = some_vec.cbegin();
        while (iter != some_vec.cend())
        {
            auto ch = (*iter++)[0];
            benchmark::DoNotOptimize(ch);
        }
    }
    benchmark::DoNotOptimize(some_vec);
}
BENCHMARK(test1);

在没有优化和gcc 8.2的情况下,test0的速度提高了1.3倍:

No-optimization-results-gcc

优化级别为O3 test0快1.1倍:

O3-gcc

使用Clang 7,它们几乎是相同的:

O3-Clang

因此,性能似乎不是问题,但如果最终插入者可以以某种方式失效,则第二个版本更安全。