I was recently reading this article by Dave Detlefs in which he presents a few cases where the CLR performs array bounds check elimination. I decided to test this myself, so I did the following:
- 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
So here's the dissassembly for a[i] = i; in 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
The cmp/jb/call is bounds checking, actually forcing the call to be executed throws an IndexOutOfRangeException.
Same thing for all array accesses, including the redundant access in Test_SimpleRedundant. So is there something wrong with my testing methodology, or the CLR doesn't actually eliminate bounds checking? I hope I'm wrong and if so I'd like to know how I can really get array bounds checking elimination.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…