Re[52]: MS забило на дотнет. Питону - да, сишарпу - нет?
От: vdimas Россия  
Дата: 10.09.21 19:14
Оценка:
Здравствуйте, vdimas, Вы писали:

Интереса ради разобрал ассемблер по ссылке:
// выделили память на стеке (что-то дохрена)
    L0000: sub rsp, 0x28

// в rcx пришло this
// rax=_indicies.Pointer (i.e. Bunch<int>._data0)
    L0004: lea rax, [rcx+8]

// r8d = _indicies.Length
    L0008: mov r8d, [rcx]

// for(i = 0;
    L000b: xor r9d, r9d
    L000e: jmp short L0013

// ===================== начало цикла ==============
// i++
    L0010: inc r9d

//  ? i < indices.Length
    L0013: cmp r9d, r8d

// выход из цикла по i==indicies.Length
    L0016: jge short L0021

// лишнее преобразование... всё-таки, в x64 Span.Length должно быть int64, т.е. nint.
    L0018: movsxd r10, r9d

// ? indices[i] <= index
// здесь соптимизирована проверка выхода за границы при вызове indices[i]
    L001b: cmp [rax+r10*4], edx

// зацикливание 
    L001f: jle short L0010
// =================== конец цикла ===================

// return (Children[i], i > 0 ? index - indices[i - 1] : index);    L0021: lea r10, [rcx+0x48]
    // r10=_children.Pointer
    L0021: lea r10, [rcx+0x48]

//  ecx = indices.Length (хотя, это значение сидит в r8d)
    L0025: mov ecx, [rcx]

// проверили выход за массив Children[i]
    L0027: cmp r9d, ecx
    L002a: jae short L005f

// rcx=Childer[i]
    L002c: movsxd rcx, r9d
    L002f: mov rcx, [r10+rcx*8]

// ? i > 0
    L0033: test r9d, r9d
    L0036: jg short L003a
    L0038: jmp short L004e

// r10d = i-1
    L003a: lea r10d, [r9-1]

// проверка выхода за диапазон indices[i - 1] (как глупо)
    L003e: cmp r10d, r8d
    L0041: jae short L005f

// r8 = i-1 (опять?)
    L0043: lea r8d, [r9-1]
    L0047: movsxd r8, r8d

// index - indices[i - 1]
    L004a: sub edx, [rax+r8*4]

// return t.Node[i]
    L004e: cmp [rcx], ecx
    L0050: add rcx, 8
    L0054: call BranchNode`2[[LeafNode`1[[System.Int32, System.Private.CoreLib]], _],[System.Int32, System.Private.CoreLib]].get_Item(Int32)
    L0059: nop
    L005a: add rsp, 0x28
    L005e: ret

// выброс IndexOutOfRangeException
    L005f: call 0x00007ffb4bfba5e0
    L0064: int3


Целевой цикл вылизан по самое нимогу.
Остальное с огрехами.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.