在for循环上调用条件(c ++)

时间:2015-05-12 09:15:16

标签: c++ performance for-loop

以下是我一直想知道的一个简单问题: 当我做这样的循环时:

for (int i = 0; i < myVector.size() ; ++i) {
    // my loop
}

每次检查条件i < myVector.size()时,是否应该在循环之前将数组的大小存储在变量中以防止每次迭代调用size()?或者编译器是否足够聪明,可以自行完成?

mySize = myVector.size();   
for (int i = 0; i < mySize ; ++i) {
    // my loop
}

我会用更复杂的条件扩展问题,例如i < myVector.front()/myVector.size()

编辑:我没有在循环中使用myVector,这里是为了给出结束条件。那更复杂的情况怎么样?

5 个答案:

答案 0 :(得分:2)

答案主要取决于循环的内容 - 它可能会在处理过程中修改向量,从而修改其大小。

但是,如果刚刚扫描了矢量,您可以提前安全地存储它的大小:

package futures

import scala.concurrent.{Future => ConcurrentTask}           // rename
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
import Utils.sleep

object FutureAsConcurrentTask extends App {

  // run some long-running task (task has type Future[Int] in this example)
  val task = ConcurrentTask {
    Cloud.executeLongRunningTask
  }

  // whenever the task completes, execute this code
  task.onComplete {
    case Success(value) => println(s"Got the callback, value = $value")
    case Failure(e) => println(s"D'oh! The task failed: ${e.getMessage}")
  }

  // do your other work
  println("A ..."); sleep(100)
  println("B ..."); sleep(100)
  println("C ..."); sleep(100)
  println("D ..."); sleep(100)
  println("E ..."); sleep(100)
  println("F ..."); sleep(100)

}

虽然在大多数课程中,“获取当前大小”等函数只是内联getter:

for (int i = 0, mySize = myVector.size(); i < mySize ; ++i) {
    // my loop
}

因此编译器可以轻松地将调用简化为只读取class XXX { public: int size() const { return mSize; } .... private: int mSize; .... }; 变量,因此预取长度不会产生任何收益。

答案 1 :(得分:1)

我说

for (int i = 0; i < myVector.size() ; ++i) {
    // my loop
}

更安全
mySize = myVector.size();   
for (int i = 0; i < mySize ; ++i) {
    // my loop
}

因为myVector.size()的值可能会发生变化(例如,循环中的push_back(value))因此您可能会错过某些元素。
如果你100%确定myVector.size()的值不会改变,那么两者都是一样的。
然而,第一个比第二个更灵活(其他开发人员可能不知道循环迭代超过固定大小,他可能会改变数组大小)。不要担心编译器,他比我们两个人组合起来更聪明。

答案 2 :(得分:1)

如果你在for循环期间没有改变vector(添加/删除)中的任何东西(这是正常情况)我会使用foreach循环

for (auto object : myVector)
{
  //here some code
}

或者如果你不能使用c ++ 11,我会使用迭代器

for (auto it = myVector.begin(); it != myVector.end(); ++it)
{
  //here some code
}

答案 3 :(得分:0)

任何智能编译器都可能会优化它。然而,为了确保我通常像这样布置我的for循环:

for (int i = myvector.size() -1; i >= 0; --i)
{

}

有几件事是不同的:

  • 迭代是以相反的方式完成的。虽然在大多数情况下这不应该成为问题。如果是我更喜欢David Haim的方法。

  • 使用--i而不是i--。从理论上讲, - i更快,虽然在大多数编译器上它都不会有所作为。

如果您不关心索引:

for (int i = myvector.size(); i > 0; --i)
{

}

也是一种选择。总的来说,我不会使用它,因为它比第一个更混乱。而且不会让你获得任何表现。

对于类似std::vectorstd::list的类型,迭代器是优先方法:

for (std::vector</*vectortype here*/>::iterator i = myVector.begin(); i != myVector.end(); ++i)
{

}

答案 4 :(得分:0)

开销非常小。 vector.size()不会重新计算任何内容,只是返回私有大小变量的值..

它比预缓存值更安全,因为当向量中弹出或推送元素时,向量内部大小变量会发生变化..

可以编写

编译器来优化它,当且仅当它可以预测在for循环运行时向量没有被ANYTHING改变。 如果那里有线程,这很难做到。

但如果没有进行任何线程,则很容易对其进行优化。