2017-04-25 112 views
1

对于for循环的清洁,我喜欢基于范围的for循环。在for循环中,我想先填充一个我知道大小的矢量,但我缺少一个索引值。我现在有两种方法来实现它,声明一个向量并添加带有push_back的元素或者创建一个初始化的向量(因为不需要分配,应该更快一点?),计算索引并插入一个元素。考虑干净代码的性能,有什么更好

问题:相对于其他方法的性能缺陷和/或是否有更好的实现方式?

在此示例代码下方,真实代码包含相对少量的项目(推测可能少于10个),但它将通过此​​过程运行数百万次。

//The vector as input for the for loop 
    std::vector<double> vecIn = { 1, 2, 3, 4, 5 }; 

    //Adding values to vectors, vector size changes on each loop right? 
    std::vector<double> vecOut1; 
    //Loop through vector with range looping 
    for (auto& val : vecIn) { 
     vecOut1.push_back(val); //In reality val is some calculated value based on the input. 
    } 

    //Adding values to initialized vector, but need to calculate index. 
    std::vector<double> vecOut2(vecIn.size()); 
    //Loop through vector with range looping 
    for (auto& val : vecIn) { 
     auto i = &val - &vecIn[0]; 
     vecOut2[i] = val; //In reality val is some calculated value based on the input. 
    } 

我喜欢短暂的第一个循环,但害怕明智的表现会更糟。

当然,我也可以在循环的开始处声明一个索引并对其进行迭代,但这似乎有点打败了清理的目的。

编辑:为了澄清,这是演示代码,我将一个向量复制到另一个向量。在实际的程序中,处理输入向量并基于输入向量计算新值。新值需要插入/附加到矢量输出。在真实代码中,输入甚至不是矢量,而是一个boost :: ublas :: matrix。

+2

对其进行配置并查看:) –

+4

使用'vector.reserve'。 – nwp

+9

如果你想复制整个矢量,你可以做'std :: vector vecOut1 = vecIn;'这个库会为你做所有的工作。包括预先分配足够的空间。 –

回答

1

你所有的第一循环所需要的是一个.reserve()在相同的数量级的性能才能发挥其作为第二个:

std::vector<double> vecOut1; 
vecOut1.reserve(vecIn.size()); 
for (auto& val : vecIn) 
    vecOut1.push_back(val); 

reserve预先分配的要求,而不改变向量size - 所以没有重新分配在循环中进行。

4

这几乎是一样的。

您可以通过执行让编译器优化你的东西:

std::vector<double> vecOut1(vecIn.begin(), vecIn.end()); 

std::vector<double> vecOut1 = vecIn 

通过这样做,你要复制vecIn到vecOut1。

另一个建议:无论您是否可以告诉您在for循环中处理的类型,请避免使用关键字auto,并指定类型。

编辑:由于OP的问题不清楚,这里有一个新的答案。

你的第一个aproach就好了。还有一些很好的选择。

如果你知道你的vecOut2载体的插入元素,你可以有指数以更好的方式访问之前的大小:

std::vector<double> vecOut2(vecIn.size()); 
for(int i = 0;i < vecOut2.size(); i++){ 
    vecOut2[i] = vecIn[i] + /* Your calculation */; 
} 

这真的取决于你想如何执行你的计算,如果计算是线性的(如果你不得不在索引之间跳转)。

+0

我编辑了我的问题以更清楚地说明我不想执行矢量复制,但提供的代码是示例代码。 –

+0

我编辑了我的答案,但您仍然不清楚要如何执行您的操作以及您的计算有多复杂。 – mvs

+0

我不同意不使用自动。将整个类型的迭代器写入复杂的数据结构非常耗时,不会使代码更具可读性,并且如果更改基础数据结构,则需要重写 –