var length = array.Length;
for (int i = 0; i < length; i++) {
//do smth
}
, CLR Array.Length. .
C#:
public int WithoutVariable() {
int sum = 0;
for (int i = 0; i < array.Length; i++) {
sum += array[i];
}
return sum;
}
public int WithVariable() {
int sum = 0;
int length = array.Length;
for (int i = 0; i < length; i++) {
sum += array[i];
}
return sum;
}
, JIT .NET Framework 4.7.2 LegacyJIT-x86:
WithoutVariable()
;int sum = 0; xor edi, edi ;int i = 0; xor esi, esi ;int[] localRefToArray = this.array; mov edx, dword ptr [ecx+4] ;int arrayLength = localRefToArray.Length; mov ecx, dword ptr [edx+4] ;if (arrayLength == 0) return sum; test ecx, ecx jle exit ;int arrayLength2 = localRefToArray.Length; mov eax, dword ptr [edx+4] ;if (i >= arrayLength2) ; throw new IndexOutOfRangeException(); loop: cmp esi, eax jae 056e2d31 ;sum += localRefToArray[i]; add edi, dword ptr [edx+esi*4+8] ;i++; inc esi ;if (i < arrayLength) goto loop cmp ecx, esi jg loop ;return sum; exit: mov eax, edi |
WithVariable()
;int sum = 0; xor esi, esi ;int[] localRefToArray = this.array; mov edx, dword ptr [ecx+4] ;int arrayLength = localRefToArray.Length; mov edi, dword ptr [edx+4] ;int i = 0; xor eax, eax ;if (arrayLength == 0) return sum; test edi, edi jle exit ;int arrayLength2 = localRefToArray.Length; mov ecx, dword ptr [edx+4] ;if (i >= arrayLength2) ; throw new IndexOutOfRangeException(); loop: cmp eax, ecx jae 05902d31 ;sum += localRefToArray[i]; add esi, dword ptr [edx+eax*4+8] ;i++; inc eax ;if (i < arrayLength) goto loop cmp eax, edi jl loop ;return sum; exit: mov eax, esi |
Meld

, — 15 . . . , :
- 0 (arrayLength);
- (arrayLength2);
, , .
:
public int WithoutVariable() {
int sum = 0;
for(int i = 0; i < array.Length; i++) {
sum += array[i] + array.Length;
}
return sum;
}
public int WithVariable() {
int sum = 0;
int length = array.Length;
for(int i = 0; i < length; i++) {
sum += array[i] + length;
}
return sum;
}
, , . :
WithoutVariable()
int sum = 0; xor edi, edi int i = 0; xor esi, esi int[] localRefToArray = this.array; mov edx, dword ptr [ecx+4] int arrayLength = localRefToArray.Length; mov ebx, dword ptr [edx+4] if (arrayLength == 0) return sum; test ebx, ebx jle exit int arrayLength2 = localRefToArray.Length; mov ecx, dword ptr [edx+4] if (i >= arrayLength2) throw new IndexOutOfRangeException(); loop: cmp esi, ecx jae 05562d39 int t = array[i]; mov eax, dword ptr [edx+esi*4+8] t += sum; add eax, edi t+= arrayLength; add eax, ebx sum = t; mov edi, eax i++; inc esi if (i < arrayLength) goto loop cmp ebx, esi jg loop return sum; exit: mov eax, edi |
WithVariable()
int sum = 0; xor esi, esi int[] localRefToArray = this.array; mov edx, dword ptr [ecx+4] int arrayLength = localRefToArray.Length; mov ebx, dword ptr [edx+4] int i = 0; xor ecx, ecx if (arrayLength == 0) (return sum;) test ebx, ebx jle exit int arrayLength2 = localRefToArray.Length; mov edi, dword ptr [edx+4] if (i >= arrayLength2) throw new IndexOutOfRangeException(); loop: cmp ecx, edi jae 04b12d39 int t = array[i]; mov eax, dword ptr [edx+ecx*4+8] t += sum; add eax, esi t+= arrayLength; add eax, ebx sum = t; mov esi, eax i++; inc ecx if (i < arrayLength) goto loop cmp ecx, ebx jl loop return sum; exit: mov eax, esi |
Meld

, . , sum array.Length, . :
int arrayLength2 = localRefToArray.Length;— .
mov edi, dword ptr [edx+4]
if (i >=arrayLength2) throw new IndexOutOfRangeException();
cmp ecx, edi
jae 04b12d39
, , .. . .
ForEach. :
public int ForEachWithoutLength() {
int sum = 0;
foreach (int i in array) {
sum += i;
}
return sum;
}
public int ForEachWithLengthWithoutLocalVariable() {
int sum = 0;
foreach (int i in array) {
sum += i + array.Length;
}
return sum;
}
public int ForEachWithLengthWithLocalVariable() {
int sum = 0;
int length = array.Length;
foreach (int i in array) {
sum += i + length;
}
return sum;
}
JIT:
ForEachWithoutLength()
;int sum = 0;
xor esi, esi
;int[] localRefToArray = this.array;
mov ecx, dword ptr [ecx+4]
;int i = 0;
xor edx, edx
;int arrayLength = localRefToArray.Length;
mov edi, dword ptr [ecx+4]
;if (arrayLength == 0) goto exit;
test edi, edi
jle exit
;int t = array[i];
loop:
mov eax, dword ptr [ecx+edx*4+8]
;sum+=i;
add esi, eax
;i++;
inc edx
;if (i < arrayLength) goto loop
cmp edi, edx
jg loop
;return sum;
exit:
mov eax, esi
xor esi, esi
;int[] localRefToArray = this.array;
mov ecx, dword ptr [ecx+4]
;int i = 0;
xor edx, edx
;int arrayLength = localRefToArray.Length;
mov edi, dword ptr [ecx+4]
;if (arrayLength == 0) goto exit;
test edi, edi
jle exit
;int t = array[i];
loop:
mov eax, dword ptr [ecx+edx*4+8]
;sum+=i;
add esi, eax
;i++;
inc edx
;if (i < arrayLength) goto loop
cmp edi, edx
jg loop
;return sum;
exit:
mov eax, esi
ForEachWithLengthWithoutLocalVariable()
;int sum = 0;
xor esi, esi
;int[] localRefToArray = this.array;
mov ecx, dword ptr [ecx+4]
;int i = 0;
xor edx, edx
;int arrayLength = localRefToArray.Length;
mov edi, dword ptr [ecx+4]
;if (arrayLength == 0) goto exit
test edi, edi
jle exit
;int t = array[i];
loop:
mov eax, dword ptr [ecx+edx*4+8]
;sum+=i;
add esi, eax
;sum+=localRefToArray.Length;
add esi, dword ptr [ecx+4]
;i++;
inc edx
;if (i < arrayLength) goto loop
cmp edi, edx
jg loop
;return sum;
exit:
mov eax, esi
xor esi, esi
;int[] localRefToArray = this.array;
mov ecx, dword ptr [ecx+4]
;int i = 0;
xor edx, edx
;int arrayLength = localRefToArray.Length;
mov edi, dword ptr [ecx+4]
;if (arrayLength == 0) goto exit
test edi, edi
jle exit
;int t = array[i];
loop:
mov eax, dword ptr [ecx+edx*4+8]
;sum+=i;
add esi, eax
;sum+=localRefToArray.Length;
add esi, dword ptr [ecx+4]
;i++;
inc edx
;if (i < arrayLength) goto loop
cmp edi, edx
jg loop
;return sum;
exit:
mov eax, esi
ForEachWithLengthWithLocalVariable()
;int sum = 0;
xor esi, esi
;int[] localRefToArray = this.array;
mov edx, dword ptr [ecx+4]
;int length = localRefToArray.Length;
mov ebx, dword ptr [edx+4]
;int i = 0;
xor ecx, ecx
;int arrayLength = localRefToArray.Length;
mov edi, dword ptr [edx+4]
;if (arrayLength == 0) goto exit;
test edi, edi
jle exit
;int t = array[i];
loop:
mov eax, dword ptr [edx+ecx*4+8]
;sum+=i;
add esi, eax
;sum+=length ;
add esi, ebx
;i++;
inc ecx
;if (i < arrayLength) goto loop
cmp edi, ecx
jg loop
;return sum;
exit:
mov eax, esi
xor esi, esi
;int[] localRefToArray = this.array;
mov edx, dword ptr [ecx+4]
;int length = localRefToArray.Length;
mov ebx, dword ptr [edx+4]
;int i = 0;
xor ecx, ecx
;int arrayLength = localRefToArray.Length;
mov edi, dword ptr [edx+4]
;if (arrayLength == 0) goto exit;
test edi, edi
jle exit
;int t = array[i];
loop:
mov eax, dword ptr [edx+ecx*4+8]
;sum+=i;
add esi, eax
;sum+=length ;
add esi, ebx
;i++;
inc ecx
;if (i < arrayLength) goto loop
cmp edi, ecx
jg loop
;return sum;
exit:
mov eax, esi
, , for ( foreach 12 , for 15).
For ForEach

, for vs foreach 1 000 000 ,
sum+=array[i];
Method | ItemsCount | Mean | Error | StdDev | Median | Ratio | RatioSD |
ForEach | 1000000 | 1.401 ms | 0.2691 ms | 0.7935 ms | 1.694 ms | 1.00 | 0.00 |
For | 1000000 | 1.586 ms | 0.3204 ms | 0.9447 ms | 1.740 ms | 1.23 | 0.65 |
sum+=array[i] + array.Length;
Method | ItemsCount | Mean | Error | StdDev | Median | Ratio | RatioSD |
ForEach | 1000000 | 1.703 ms | 0.3010 ms | 0.8874 ms | 1.726 ms | 1.00 | 0.00 |
For | 1000000 | 1.715 ms | 0.2859 ms | 0.8430 ms | 1.956 ms | 1.13 | 0.56 |
foreach

ForEachWithoutLength. . ForEach - , - . - JIT .
ForEachWithLengthWithoutLocalVariable. , sum+=length arrayLength, , . , N + 1, N — .
ForEachWithLengthWithLocalVariable. ForEachWithLengthWithoutLocalVariable, . arrayLength, , length . , . .
. , , , : . , , Foreach For.