C# 静态字符串中的属性长度是在运行时还是在编译期间计算的?

C# 静态字符串中的属性长度是在运行时还是在编译期间计算的?,c#,performance,C#,Performance,如果我有这个密码 if ("test".Length == 4) 它是否计算过这个长度,或者编译器计算它并在IL代码中使用一个数字 如果在运行时完成,则意味着包含此类内容的代码比包含数字的代码慢 比如说 int length = 2 + 4; 会比 int length = 2 + "test".Length; 这就是我想知道的 编辑:根据rant的说法,我自己也对它进行了基准测试,它似乎运行得同样快,但我不明白为什么,因为回复告诉我它产生了两个不同的IL代码 那么,在代码中使用它而不降低

如果我有这个密码

if ("test".Length == 4)
它是否计算过这个
长度
,或者编译器计算它并在IL代码中使用一个数字

如果在运行时完成,则意味着包含此类内容的代码比包含数字的代码慢

比如说

int length = 2 + 4;
会比

int length = 2 + "test".Length;
这就是我想知道的

编辑:根据rant的说法,我自己也对它进行了基准测试,它似乎运行得同样快,但我不明白为什么,因为回复告诉我它产生了两个不同的IL代码


那么,在代码中使用它而不降低性能是否安全呢?

我刚刚在LINQPad中编译了它,下面是生成的IL

IL_0001:  ldstr       "test"
IL_0006:  callvirt    System.String.get_Length
IL_000B:  ldc.i4.4    
IL_000C:  ceq         
因此,它似乎是在运行时完成的。在启用和不启用编译器优化的情况下,结果相同


的确,当C#编译器能够将
2+4
转换为
ldc.i4.6
,但
2+“test”。Length
需要一个函数调用。但是,正如其他人指出的那样,JIT编译器可能比C#编译器能够对这段代码进行更多的优化。

我刚刚在LINQPad中编译了它,下面是生成的IL

IL_0001:  ldstr       "test"
IL_0006:  callvirt    System.String.get_Length
IL_000B:  ldc.i4.4    
IL_000C:  ceq         
因此,它似乎是在运行时完成的。在启用和不启用编译器优化的情况下,结果相同


的确,当C#编译器能够将
2+4
转换为
ldc.i4.6
,但
2+“test”。Length
需要一个函数调用。但是,正如其他人指出的那样,JIT编译器可能比C编译器能够对该代码进行更多的优化。

在我的平台上,使用VS 2010 for.NET 4编译的代码,IL DASM显示

调试 释放 这意味着没有编译时优化。然而,CLR抖动可以优化这一点。通过查看汇编代码可以看到这种优化的结果,下面是结果


在我的平台上,针对
x86
平台的发行版编译的代码似乎进行了运行时比较,而jitter没有优化代码

我使用的代码

class Program
{
    static void Main(string[] args)
    {
        if ("test".Length == 4) { }
    }
}
这是为
if
块生成的汇编代码的一部分。第17行比较
测试
字符串的值

if ("test".Length == 4)
00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  sub         esp,8 
00000006  mov         dword ptr [ebp-4],ecx 
00000009  cmp         dword ptr ds:[00148ED4h],0 
00000010  je          00000017 
00000012  call        5D664D0A 
00000017  mov         ecx,dword ptr ds:[035F2188h] 
0000001d  cmp         dword ptr [ecx],ecx 
0000001f  call        5D4CA74B 
00000024  mov         dword ptr [ebp-8],eax 
00000027  nop

在我的平台上,IL DASM显示了用VS2010为.NET 4编译的代码

调试 释放 这意味着没有编译时优化。然而,CLR抖动可以优化这一点。通过查看汇编代码可以看到这种优化的结果,下面是结果


在我的平台上,针对
x86
平台的发行版编译的代码似乎进行了运行时比较,而jitter没有优化代码

我使用的代码

class Program
{
    static void Main(string[] args)
    {
        if ("test".Length == 4) { }
    }
}
这是为
if
块生成的汇编代码的一部分。第17行比较
测试
字符串的值

if ("test".Length == 4)
00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  sub         esp,8 
00000006  mov         dword ptr [ebp-4],ecx 
00000009  cmp         dword ptr ds:[00148ED4h],0 
00000010  je          00000017 
00000012  call        5D664D0A 
00000017  mov         ecx,dword ptr ds:[035F2188h] 
0000001d  cmp         dword ptr [ecx],ecx 
0000001f  call        5D4CA74B 
00000024  mov         dword ptr [ebp-8],eax 
00000027  nop

使用编译器优化?@DmitryDovgopoly,带和不带。这实际上意味着这样做是件坏事。我认为这样的代码和fastNote一样,都是关于C#编译器的。不知道抖动是什么造成的。有编译器优化吗?@DmitryDovgopoly,有和没有。这实际上意味着这样做是件坏事。我认为这样的代码和fastNote一样,都是关于C#编译器的。不知道抖动是什么造成的。这超出了微观优化的范围。这将是一个非常困难(罕见)的问题,找到生产代码。这是超越微观优化。这将是非常困难(罕见)找到生产代码,这是一个问题。当然你可以检查。只需降低到x86级别即可。@Henkholtman感谢您的审阅。我添加了汇编代码。在我的平台上似乎没有执行任何优化。当然可以检查。只需降低到x86级别即可。@Henkholtman感谢您的审阅。我添加了汇编代码。看起来我的平台上没有进行任何优化。