我最近阅读了Dave Detlefs的这篇文章,其中他提出了一些CLR执行数组边界检查消除的情况。我决定自己测试一下,所以我做了以下几点:
- Opened Visual Studio 2010 Ultimate SP1
- Created a new C# project of type Console Application (targeting .NET 4 Client Profile by default)
Added the following code (all sub-methods are taken directly from the article):
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]; } }
Switched to Release mode; verified that "Optimize Code" is checked in the Build options
- Added a breakpoint to each array access, started debugging (F5) and opened the Dissassembly window
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实际上没有消除边界检查?我希望我是错的,如果是这样,我想知道如何真正消除数组边界检查。