[英]Effect of consts and variablization of operations in C# performance
常量通常用于C / C ++编程中,作为产生更清晰代码的一种方式。 有时也可能存在优化益处。 但是,我想知道除了更易读的代码之外,从C#中声明值是只读还是有效可以获得什么好处。
假设我有以下C#代码:
public Double HalfPiSomething(Int32 input)
{
return input + (Math.PI / 2);
}
这是一个相当简单的示例,但每次调用该方法时,我们将Math.PI
除以2,将其添加到输入,并将其返回到调用语句。
让我们使用该代码并在包含类的某个位置使Math.PI / 2
成为自己的变量:
private Double _halfPi = Math.PI / 2;
public Double HalfPiSomething(Int32 input)
{
return input + _halfPi;
}
显然,采用Math.PI / 2
的操作并将其置于自己的变量中是一个好主意,就像基本的编码实践一样,特别是如果在类中的多个点使用所述值...它不在这里,但让我们只是假装。
最后,因为_halfPi
永远不会改变,所以让它成为const
:
private const Double _halfPi = Math.PI / 2;
public Double HalfPiSomething(Int32 input)
{
return input + _halfPi;
}
我想知道的是,除了作为C#的良好编码实践并使代码更容易理解并且更难以犯错之外,是否有好处 - 特别是在性能方面 - 做我上面做的事情? 值是否会在本地内存中保留更长时间?
每次调用该方法时,我们将
Math.PI
除以2
,将其添加到输入,并将其返回到调用语句。
不,这不是正在发生的事情:C#编译器在编译时评估常量表达式。 此外,当混合常量和非常量的表达式具有可在编译时计算的子表达式时,编译器会预先计算该值,就好像它是单个常量一样。
编译器将Math.PI / 2
子表达式标识为常量,执行计算,并生成将输入添加到除法的预计算结果的代码。
我想知道的是,除了作为C#的良好编码实践并使代码更容易理解并且更难以犯错之外,是否有好处 - 特别是在性能方面 - 做我上面做的事情?
不,没有理由做编译器的工作,除非它导致更清晰。
值是否会在本地内存中保留更长时间?
常量值被“烘焙”到编译器生成的代码中。 它们不是本地数据存储器的一部分(尽管它们肯定在内存中,只要代码在内存中)。
大多数这些次要优化都是由编译器和JIT为您处理的。 例如,如果我编译你的第一块代码,反编译的结果是
public double HalfPiSomething(int input)
{
return (double)input + 1.5707963267949;
}
因此,除非您遇到严重的性能问题,然后确定作为瓶颈的代码块,否则我认为从优化角度来看这些小细节并不值得担心。 在那之后,在那个集中的代码上,花一些时间进行优化是值得的。
标准警告:根据您的具体情况readonly
尝试和测量不同的代码变体 - const
, readonly
,字段/属性对性能有不同的影响,可能会有所不同。
常量表达式是在编译时计算的 - 所以如果所有子表达式都是常量,那么通过声明额外的常量就不会获得任何东西:
const double halfPi = Math.PI / 2;
var r1 = halfPi * 3;
var r2 = Math.PI / 2 * 3;
r1
和r2
将初始化为完全相同的值。
Readonly是运行时值,并且可以使用JIT内联调用,但您仍然可以获得访问字段的费用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.