【发布时间】:2014-06-02 03:14:43
【问题描述】:
据我了解,当你写一个类似于这个的for循环时
for (int i = 0; i < SOME_NUM; i++) {
if (true)
do_something();
else
do_something_else();
}
此操作的时间复杂度主要受if (true) 语句的影响,因为for 循环迭代实际上并不涉及i 与SOME_NUM 的任何比较,编译器实际上只会运行循环SOME_NUM 次。如果我错了,请纠正我。
但是,如果这是正确的,那么以下嵌套的 for 循环的行为如何?
for (int i = 0; i < SOME_NUM; i++) {
for (int j = 0; j < i; j++) {
do_something();
}
}
内部 for 循环中的 j 现在是 i 的上限,该值在每次循环重新启动时都会更改。编译器将如何编译它?这些嵌套的 for 循环本质上是否表现得像一个带有 while 循环的 for 循环?如果您正在编写一个使用嵌套 for 循环的算法,其中内部计数变量取决于外部计数变量,您是否应该担心这会对您的算法的复杂性造成什么影响?
【问题讨论】:
-
我不会在这里称其为“时间复杂度”,因为这通常指的是运行时的 Big-Oh。而且,是的,for 循环中的比较是执行的,至少在 C++ 意义上,在更广泛的意义上是的,优化器可以优化它,但它与 for vs while 循环无关。归根结底,这一切都变成了组装,如果需要在那里进行比较,那就可以了。虽然它可能会展开它。 while 和 for 循环实际上是相同的。编译器会优化它可以优化的任何东西,它可以同时优化两者,而且它非常擅长。
-
在这个简单的情况下,我猜编译器将能够检测到内部循环是没有意义的,并且整体 do_something 被调用了一些恒定的次数。此外,在这里花时间的另一件大事是函数调用,但是编译器也可能内联它。在这里花时间的另一件事是分支预测。也就是说,如果在运行时处理器预测 if 块将被占用,而不是你刷新你的管道。但是,在这种情况下,if 语句将被完全编译为优化代码,因为它始终为真。
-
如果有疑问,请查看您的源代码生成的程序集。调试它。您将更好地了解编译器可以和将要做的各种事情,这也取决于程序集中可用的指令种类,具体取决于您的平台。但是,如果您想查看优化,请确保在编译时打开它们。
-
这很有帮助,谢谢
标签: c++ loops for-loop compiler-construction