arrays边界检查CLR中的消除?

我最近阅读了Dave Detlefs的这篇文章 ,其中他介绍了一些CLR执行数组边界检查消除的情况。 我决定自己测试一下,所以我做了以下几点:

  • 打开Visual Studio 2010 Ultimate SP1
  • 创建了一个类型为Console Application的新C#项目(默认情况下以.NET 4 Client Profile为目标)
  • 添加了以下代码(所有子方法都直接来自文章):

    class Program { static void Main(string[] args) { int[] array = new int[30]; Test_SimpleAscend(array); Test_SimpleRedundant(array, 3); foreach (int i in array) { Console.WriteLine(i); } } static void Test_SimpleAscend(int[] a) { for (int i = 0; i < a.Length; i++) a[i] = i; } static void Test_SimpleRedundant(int[] a, int i) { int k = a[i]; k = k + a[i]; } } 
  • 切换到发布模式; validation在“构建”选项中选中“优化代码”

  • 为每个arrays访问添加了一个断点,开始调试(F5)并打开Dissassembly窗口

所以这是[i] = i的反汇编; 在Test_SimpleAscend中:

  a[i] = i; 00000024 mov eax,dword ptr [ebp-4] 00000027 mov edx,dword ptr [ebp-8] 0000002a cmp eax,dword ptr [edx+4] 0000002d jb 00000034 0000002f call 64FD6E08 00000034 mov ecx,dword ptr [ebp-4] 00000037 mov dword ptr [edx+eax*4+8],ecx 

cmp / jb / call是边界检查,实际上强制执行调用会抛出IndexOutOfRangeException。

所有数组访问都是一样的,包括Test_SimpleRedundant中的冗余访问。 那么我的测试方法有问题,或者CLR实际上没有消除边界检查? 我希望我错了,如果是的话,我想知道如何才能真正获得数组边界检查消除。

感谢Cody Gray的评论,我已经设法回答了我自己的问题:

默认情况下,调试时禁用JIT优化。 要解决此问题,可以进入调试 – >选项和设置 – >调试 – >常规,并取消选中“启用我的代码”和“在模块加载时抑制JIT优化”。

另请参阅http://msdn.microsoft.com/en-us/library/ms241594.aspx

启用优化后,将按照公布的方式删除边界检查。

我会把它留在这里用于记录目的。