在 C# 中的字段上使用 const 或 readonly 修饰符是否有任何性能优势?

问题描述 投票:0回答:3

仅使用私有变量时,与常规可修改字段相比,使用

const
readonly
字段是否有任何性能优势?

例如:

public class FooBaar
{
     private string foo = "something";
     private const string baar = "something more"

     public void Baaz()
     {
         //access foo, access baar
     }
}

在上面的示例中,您可以看到有两个字段:

foo
baar
。两者在课堂之外都无法访问,所以为什么很多人更喜欢在这里使用
const
,而不是仅仅使用
private
const
是否提供任何性能优势?


这个问题之前被社区关闭了,因为人们把这个问题误解为

const
readonly
在性能方面有什么区别?”
,已经在这里回答了:之间有什么区别const 和只读?.
但我真正的意思是,“通过使用
const
readonly
与不使用其中任何一个相比,我是否能获得任何性能优势”

c# performance constants readonly
3个回答
27
投票

const 会被编译器优化以内联到代码中,而 readonly 不能内联。但是,您不能创建所有类型的常量 - 因此在这里您必须将它们设置为只读。

因此,如果您的代码中需要一个常量值,您应该首先考虑使用 const(如果可能的话),如果没有,那么 readonly 可以让您获得安全性,但不会获得性能优势。

举个例子:

public class Example
{
    private const int foo = 5;
    private readonly Dictionary<int, string> bar = new Dictionary<int, string>();

    //.... missing stuff where bar is populated

    public void DoSomething()
    {
       Console.Writeline(bar[foo]);

       // when compiled the above line is replaced with Console.Writeline(bar[5]);
       // because at compile time the compiler can replace foo with 5
       // but it can't do anything inline with bar itself, as it is readonly
       // not a const, so cannot benefit from the optimization
    }
}

0
投票

我也有同样的疑问,并且我使用了一个工具来检查使用静态和只读修饰符所产生的 IL 输出。

检查这个例子:

public class C {

    const string test = "stuff";
    private static string test2 = "stuff2";

    public static void M() {
        System.Console.WriteLine(test);
        System.Console.WriteLine(test2);
    }
}

M() 的 IL 输出:

 IL_0000: nop
 IL_0001: ldstr "stuff"
 IL_0006: call void [System.Console]System.Console::WriteLine(string)
 IL_000b: nop
 IL_000c: ldsfld string C::test2
 IL_0011: call void [System.Console]System.Console::WriteLine(string)
 IL_0016: nop
 IL_0017: ret

它不太可能在当前的硬件中产生任何性能差异,但是当CPU执行指令时,常量似乎会将数据携带到word中,而静态引用将携带一个内存指针,这将使CPU 检索某些寄存器/L1 缓存等中的值。

此处的完整输出:https://gist.github.com/VagnerGon/e8f48a652cc4f234c2ab060a5eeb7d2e


-3
投票

我不会太担心这些构造的性能,直到您遇到一段需要您进行此类测量的关键代码。它们的作用是确保代码的正确性,而不是出于性能原因。

© www.soinside.com 2019 - 2024. All rights reserved.