Open
Description
I've looked into #109677 but didn't quickly find a duplicate.
This code still has a bound check as I can see on Sharplab and in performance impact on microbenchmarks:
public class C {
private int[] _arr;
private int _count = 0;
public void M() {
var arr = _arr;
var capacity = arr.LongLength;
uint index = (uint)System.Random.Shared.Next(0, (int)capacity);
var c = 0;
while (true)
{
if (index >= arr.LongLength)
{
c++;
if(c > 1)
break;
index = 0;
}
var _ = arr[index]; // index is in [0, arr.LongLength) range
index++;
}
}
}
JITted code from Sharplab:
; Core CLR 9.0.325.11113 on x86
C..ctor()
L0000: ret
C.M()
L0000: push ebp
L0001: mov ebp, esp
L0003: push esi
L0004: mov ecx, [ecx+4]
L0007: mov esi, [ecx+4]
L000a: push esi
L000b: mov ecx, [0x8cd1fb8]
L0011: xor edx, edx
L0013: call dword ptr [0xf4b3b84]
L0019: xor edx, edx
L001b: jmp short L0025
L001d: nop
L001e: nop
L001f: nop
L0020: cmp eax, esi
L0022: jae short L0036
L0024: inc eax
L0025: cmp esi, eax
L0027: ja short L0020
L0029: inc edx
L002a: cmp edx, 1
L002d: jg short L0033
L002f: xor eax, eax
L0031: jmp short L0020
L0033: pop esi
L0034: pop ebp
L0035: ret
L0036: call Internal.Runtime.CompilerHelpers.ThrowHelpers.ThrowIndexOutOfRangeException()
L003b: int3
I have to use Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(arr), (nuint)index)
, but without bound-checks that may be slightly faster and much nicer.
Using else
eliminates BCs, but has overheads on its own.