对于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。
答案 0 :(得分:4)
几乎是一样的。
您可以通过执行以下操作让编译器为您优化:
std::vector<double> vecOut1(vecIn.begin(), vecIn.end());
或
std::vector<double> vecOut1 = vecIn
通过执行此操作,您将vecIn复制到vecOut1。
另一个建议:你是否能告诉你在for循环中处理的类型,避免使用关键字auto
,并指定类型。
编辑:由于OP问题不明确,这是一个新答案。
你的第一个方法很好。还有一些不错的选择。
如果您在插入元素之前知道vecOut2向量的大小,则可以更好地访问索引:
std::vector<double> vecOut2(vecIn.size());
for(int i = 0;i < vecOut2.size(); i++){
vecOut2[i] = vecIn[i] + /* Your calculation */;
}
这实际上取决于您希望如何执行计算,以及计算是否为线性(如果您必须在索引之间跳转)。
答案 1 :(得分:1)
您的第一个循环需求是.reserve()
,其播放速度与第二个相同:
std::vector<double> vecOut1;
vecOut1.reserve(vecIn.size());
for (auto& val : vecIn)
vecOut1.push_back(val);
reserve
预先分配所请求的元素而不更改向量size
- 因此循环中不会重新分配。