如果你有这样的方法:
float method(myClass foo)
{
return foo.PrivateVar() + foo.PrivateVar();
}
这样做总是更快/更好吗?:
float method(myClass foo)
{
float temp = foo.PrivateVar();
return temp + temp;
}
我知道你不应该在for循环中调用像foo.PrivateVar()
这样的调用,因为当你实际上只需要使用一次值时(在某些情况下,它会对它进行多次计算。) p>
for (int i = 0; i < foo.PrivateInt(); i++)
{
//iterate through stuff with 'i'
}
从这个开始,我假设将第一个例子的代码更改为第二个例子,但后来人们告诉我不要试图比编译器更聪明!并且它可以很好地内联电话。
我不想描述任何内容,我只想要一些简单的规则来进行良好的练习。我正在为求职申请编写一个演示版,我不希望任何人看到代码并看到一些新手的错误。
答案 0 :(得分:4)
这完全取决于PrivateVar()
正在做什么以及它在哪里定义等。如果编译器可以访问PrivateVar()
中的代码并且通过调用函数可以保证没有副作用,它可以做CSE,这基本上就是你在第二个代码示例中所做的。
你的for循环完全相同。因此,如果你想确定它只被评估一次,因为它是一个非常昂贵的功能(这也意味着保证没有副作用,即使没有副作用也很棘手)明确地写它。
如果PrivateVar()
只是一个吸气剂,请编写更清晰的代码 - 即使编译器可能不执行CSE,性能差异在99.9999%的情况下也无关紧要。
编辑:CSE代表Common Subexpression eliminiation并且完全符合它所代表的含义;)维基页面显示了一个简单乘法的示例,但我们也可以为更大的代码构造执行此操作,例如a功能调用。
在所有情况下,我们必须保证只评估代码一次不会改变语义,即为此代码执行CSE:
a = b++ * c + g;
d = b++ * c * d;
并将其更改为:
tmp = b++ * c;
a = tmp + g;
d = tmp * d;
显然是非法的(对于函数调用,这显然有点复杂,但原理相同)。