Sangat sering saya perhatikan bahwa orang menulis seperti ini:
var length = array.Length;
for (int i = 0; i < length; i++) {
    
}
, 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
 | 
, β 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
 
 | 
, . , 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
 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
 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
 , , for ( foreach 12 , for 15).
, 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 For. ? JIT.
ForEachWithoutLength. . ForEach - , - . - JIT .
ForEachWithLengthWithoutLocalVariable. , sum+=length arrayLength, , . , N + 1, N β .
ForEachWithLengthWithLocalVariable. ForEachWithLengthWithoutLocalVariable, . arrayLength, , length . , . .
. , , , : . , , Foreach For.