sek*_*t64 6 c++ optimization visual-c++
我在VC++中有以下代码:
for (int i = (a - 1) * b; i < a * b && i < someObject->someFunction(); i++)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
据我所知,编译器优化了所有这些算术运算,并且它们不会在每个循环上执行,但我不确定它们是否可以告诉上面的函数每次都返回相同的值并且它不需要每次都要打电话.
将所有计算保存到变量中,或者仅依靠编译器优化来获得更易读的代码是一种更好的做法吗?
int start = (a - 1) * b;
int expra = a * b;
int exprb = someObject->someFunction();
for (int i = startl i < expra && i < exprb; i++)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
简答:这取决于.如果编译器可以推断出someObject->someFunction()每次运行并且一旦两者产生相同的效果就缓存结果,则允许(但不保证)这样做.这种静态分析是否可行取决于您的程序:具体来说,静态类型someObject是什么,它的动态类型是什么,以及someFunction()实际做什么,是否virtual等等.
在一般情况下,如果只需要进行一次,编写代码以这样一种方式,它可以只能做一次,绕过需要担心什么,编译器可能会做:
int start = (a - 1) * b;
int expra = a * b;
int exprb = someObject->someFunction();
for (int i = start; i < expra && i < exprb; i++)
// ...
Run Code Online (Sandbox Code Playgroud)
或者,如果你是简洁的:
for (int i = (a - 1) * b, expra = a * b, exprb = someObject->someFunction();
i < expra && i < exprb; i++)
// ...
Run Code Online (Sandbox Code Playgroud)
如果函数与调用者驻留在同一个编译单元中,编译器通常可以推导出一些关于它的事实 - 例如,它的输出可能不会随后调用而改变.然而,一般情况并非如此.
在您的示例中,为这些简单的算术表达式分配变量并不会真正改变与生成的对象代码有关的任何内容,并且在我看来,这使得代码的可读性降低.除非你有一堆长表达式无法合理地放在一行或两行中,否则你应该避免使用临时变量 - 如果没有其他原因,那么只是为了减少命名空间污染.
使用临时变量意味着程序员的管理开销很大,以便将它们分开并避免意外的副作用.它还使得重用代码片段变得更加困难.
另一方面,将函数的结果赋给变量可以通过显式避免多个函数调用来帮助编译器更好地优化代码.
就个人而言,我会这样做:
int expr = someObject->someFunction();
for (int i = (a - 1) * b; i < a * b && i < expr; i++)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)