2

如果我有这个代码

if ("test".Length == 4)

它甚至计算过这个Length或编译器计算它并在IL代码中使用一个数字吗?

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

例如

int length = 2 + 4;

会比

int length = 2 + "test".Length;

这就是我想知道的

编辑:每个咆哮我自己对此进行了基准测试,它似乎运行得同样快,但是我不明白为什么,因为回复告诉我它正在生成 2 个不同的 IL 代码?

那么在不降低性能的情况下在代码中使用它是否安全?

4

2 回答 2

3

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

调试

...
IL_0001:  ldstr      "test"
IL_0006:  callvirt   instance int32 [mscorlib]System.String::get_Length()
...

释放

...
IL_0000:  ldstr      "test"
IL_0005:  callvirt   instance int32 [mscorlib]System.String::get_Length()
...

这意味着没有编译时优化。但是,CLR 抖动可能会对此进行优化。通过查看汇编代码可以看到这种优化的结果,这是结果

在此处输入图像描述

在我的平台上,在 Release for platform 中编译的代码x86似乎进行了运行时比较,并且抖动没有优化代码。

我使用的代码

class Program
{
    static void Main(string[] args)
    {
        if ("test".Length == 4) { }
    }
}

这是为if块生成的汇编代码的一部分。test在线比较字符串的值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
于 2013-04-04T12:39:39.370 回答
1

我只是在 LINQPad 中编译它,这是生成的 IL。

IL_0001:  ldstr       "test"
IL_0006:  callvirt    System.String.get_Length
IL_000B:  ldc.i4.4    
IL_000C:  ceq         

所以看起来它是在运行时完成的。开启和不开启编译器优化的结果是一样的。

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

于 2013-04-04T12:33:01.923 回答