C#中常量和变量操作对性能的影响

4

常量在C/C++编程中经常被用作产生更清晰代码的一种方式。有时也可能存在优化方面的好处。但是,我想知道在C#中将值声明为readonly或const除了可以使代码更易读之外,还能获得什么好处。

假设我有以下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#优秀编码实践以及使代码更易理解和更难出错之外,做我上面做的事情还有什么好处-尤其是与性能相关的好处吗?该值在本地内存中停留更长时间吗?
3个回答

6
每次调用该方法时,我们将Math.PI除以2,加上输入,然后将其返回给调用语句。 不,实际情况并非如此:C#编译器在编译时计算常量表达式。此外,当一个混合了常量和非常量的表达式有子表达式可以在编译时计算时,编译器会像单个常量一样预先计算它的值。 编译器将Math.PI / 2子表达式识别为常量,并执行计算,生成将输入添加到预计算除法结果的代码。 我想知道的是,除了成为C#良好的编码实践并使代码更易于理解和难以出错之外,是否有好处-特别是关于性能-做我上面做的事情? 不,除非它带来更多的清晰度,否则没有必要让编译器来做它的工作。 该值在本地内存中保留时间更长吗? 常量值被嵌入编译器生成的代码中。它们不是本地数据内存的一部分(尽管它们肯定在内存中,只要代码在内存中)。

3
大多数这些小的优化都是由编译器和JIT自动处理的。例如,如果我编译你的第一段代码,反编译结果如下:
    public double HalfPiSomething(int input)
    {
        return (double)input + 1.5707963267949;
    }

因此,我认为从优化的角度来看,如果您没有遇到严重的性能问题,就不值得担心这些细节,然后确定瓶颈代码块。在那之后,针对那部分专注的代码,花费一些时间进行优化是值得的。

0
标准警告:针对特定情况,请尝试自己测量不同代码变体-const,readonly,字段/属性对性能有不同的影响,可能会有所不同。
常量表达式在编译时计算-因此,如果所有子表达式都是常量,则通过声明附加常量不会获得任何优势:
const double halfPi = Math.PI / 2;
var r1 = halfPi * 3;    
var r2 = Math.PI / 2 * 3;

r1r2将被初始化为完全相同的值。

只读变量是运行时值,调用可能会与JIT内联,但您仍然需要访问字段的付款。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接