Re[53]: MS забило на дотнет. Питону - да, сишарпу - нет?
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.09.21 02:19
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, vdimas, Вы писали:


V>Интереса ради разобрал ассемблер по ссылке:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


V>Целевой цикл вылизан по самое нимогу.

V>Остальное с огрехами.

L0054 убивает всю производительность. В прошлой инкарнации этот метод был циклом c FindChild до тех пор, пока не дойдём до листа, и дети и индексы были массивами (+1 к косвенности), но при этом this[] работал быстрее, чем у штатного System.Collections.Immutable.ImmutableList.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.