【发布时间】:2011-09-14 06:28:30
【问题描述】:
我正在为图形编写一个小型的专用 C99 库,我经常得到以下形式的循环:
for(int i = 0; i < graph->nvertices; ++i) {
// ...
}
我想知道这是否是一种好习惯,尤其是在紧密循环的情况下。起初,我认为编译器会足够聪明,只查看一次“graph->nvertices”,而不是在每次迭代时查看它,但这似乎是不可能的,因为 graph->nvertices 可能会在循环内发生变化。 Is 写起来更聪明更快捷:
const int N = graph->nvertices;
for(int i = 0; i < N; ++i) {
// ...
}
它似乎更快,因为它不需要多次查看指针,但它确实需要创建一个新变量。
注意:我想在这种情况下,能够阅读一些汇编代码以了解编译器实际在做什么是件好事,如果有人有很好的参考,我愿意接受建议。
【问题讨论】:
-
一般来说,我什至不在乎,只用少一行的那个。如果有问题的循环成为热点,添加它是微不足道的,事实证明这种微优化有显着帮助。
-
首先,如果
graph->nvertices在循环过程中发生变化会发生什么?第二个版本可能更快也可能不会更快,但它在语义上有所不同。 -
@David:没错,第二个版本实际上是声明上限不会改变。
-
请注意,假设您实际上并没有在循环中对其进行修改,那么编译器是否会优化重读
graph-nvertices主要取决于(1)是否有足够的寄存器来保持缓存无论如何,以及(2)您是否在循环中使用char指针或与nvertices相同类型的指针(可以别名)。
标签: c performance pointers loops