2011-10-06 52 views
2

代码类方法调用是否会在for循环中进行优化?

for (size_t i = 0; i < myClassObject.Method(); ++i) 
    some work; 

我想知道如果编译器将优化出来的方法调用,并把它变成这样?

size_t result = myClassObject.Method(); 
for (size_t i = 0; i < result; ++i 
    some work; 

如果它是一个函数调用,它会影响吗?我担心的是,我可能会对该方法进行1000次不需要的调用,但我更愿意在条件中使用方法调用编写它。

+0

类似的问题在这里http://stackoverflow.com/questions/5607762/what-does-code-motion-mean-for-loop-invariant-code-motion – srikanta

+0

无所谓如果它是一个方法调用或纯C风格的函数调用中,允许编译器优化它的要求是相同的。 – Mat

+0

这是受广泛实施的环路提升优化,又称“环路不变代码运动”。所以,是的。 http://en.wikipedia.org/wiki/Loop-invariant_code_motion –

回答

4

你应该在代码中声明你想要做什么。如果你需要一笔款项,你就不会编写代码,而只是因为你喜欢这样做而增加代码。它需要一个智能编译器来实现对Method()的调用没有副作用,并且主体的循环不会以任何方式直接或间接修改Method()中使用的参数。

我个人的偏好,为了做我想做什么,因为我喜欢它写出来,就是:

for (size_t i = 0, result = myClassObject.Method(); i < result; ++i) 
    some work; 
+0

我检查了你的答案,所以你可以有你的威士忌晚上。谢谢@Kerrek也 – Mobius

4

这取决于编译器是否能够证明该调用的结果不可能改变循环体,所以不要依赖它。如果你想明确地提起,标准的写法是这样的:

for (std::size_t i = 0, end = myClassObject.Method(); i != end; ++i) 
{ 
    // ... 
} 

这同样适用于基于迭代器的循环。

+0

我们通常与我们的答案一致,我们应该开始一个俱乐部! :P –

+0

@ K-ballo:我建议换档,所以我可以有无SO威士忌的夜晚:-) –

1

通常,这将是不正确的优化,因为该方法可能不会在每次调用时返回相同的结果。考虑它是否返回当前时间。

如果方法定义可在同一编译单元(中包含的头文件或同一个源文件)它的编译器很简单地告诉它总是返回相同的结果,那么你可能得到这个优化。如果该方法被宣布为inline,我认为这很可能。

我相信gcc至少现在有一些编译标志的模块间优化,也可以跨源文件边界做到这一点。不知道其他编译器。