Код: Выделить всё
[SimpleJob(RuntimeMoniker.Net90)]
[SimpleJob(RuntimeMoniker.Net10_0)]
[MemoryDiagnoser]
[HardwareCounters(BenchmarkDotNet.Diagnosers.HardwareCounter.CacheMisses)]
public class BenchmarkArray
{
private const int Size = 10000;
[Benchmark(Baseline = true)]
public void ByRow()
{
var a = new int[Size, Size];
for (int i = 0; i < Size; i++)
{
for (int j = 0; j < Size; j++)
{
a[i, j] = 1;
}
}
}
[Benchmark]
public void ByColumn()
{
var a = new int[Size, Size];
for (int i = 0; i < Size; i++)
{
for (int j = 0; j < Size; j++)
{
a[j, i] = 1;
}
}
}
}

Метод
Задание
Время выполнения
Среднее
Ошибка
StdDev
Соотношение
RatioSD
CacheMiisses/Op
Gen0
Gen1
Gen2
Выделено
Коэффициент распределения
По строкам
.NET 10.0
.NET 10.0
88,33 мс
1,710 мс
2,506 мс
1,00
0,04
839,652
500,0000
500,0000
500,0000
381,47 МБ
1,00
По столбцу
.NET 10.0
.NET 10.0
604,82 мс
11,852 мс
18,099 мс
6,85
0,30
131 136 083
-
-
-
381,47 МБ
1,00
По строке
.NET 9.0
.NET 9.0
74,40 мс
0,433 мс
0,405 мс
1,00
0,01
385 752
833,3333
833.3333
833.3333
381,47 МБ
1,00
Поколонке
.NET 9.0
.NET 9.0
547,86 мс
2,367 мс
1,976 мс
7,36
0,05
132 626 295
-
-
-
381,47 МБ
1,00
Количество промахов в кэше увеличилось, а количество коллекций GC уменьшилось.
В чем причина этих изменений по сравнению с .NET 9?
ОБНОВЛЕНИЕ
Как предложено в комментариях, я включил DisassemblyDiagnoser и получил следующие результаты (для ясности прикрепляю только для метода ByRow, где были обнаружены наиболее существенные различия)
.NET 10.0.0 (10.0.0, 10.0.25.52411), X64 RyuJIT x86-64-v3
Код: Выделить всё
; ConsoleAppTest.BenchmarkArray.ByRow()
push rsi
push rbx
sub rsp,28
xor eax,eax
mov [rsp+20],rax
mov dword ptr [rsp+20],2710
mov dword ptr [rsp+24],2710
lea r8,[rsp+20]
mov rcx,offset MT_System.Int32[,]
mov edx,2
call qword ptr [7FFE915A58C0]; System.Array.CreateInstanceMDArray(IntPtr, UInt32, Void*)
xor ecx,ecx
mov edx,[rax+18]
mov r8d,[rax+10]
M00_L00:
xor r10d,r10d
mov r9d,ecx
sub r9d,edx
M00_L01:
mov r11d,r9d
cmp r11d,r8d
jae short M00_L02
mov ebx,[rax+14]
imul r11d,ebx
mov esi,r10d
sub esi,[rax+1C]
cmp esi,ebx
jae short M00_L02
add r11d,esi
mov dword ptr [rax+r11*4+20],1
inc r10d
cmp r10d,2710
jl short M00_L01
inc ecx
cmp ecx,2710
jl short M00_L00
add rsp,28
pop rbx
pop rsi
ret
M00_L02:
call CORINFO_HELP_RNGCHKFAIL
int 3
; Total bytes of code 145
Код: Выделить всё
; System.Array.CreateInstanceMDArray(IntPtr, UInt32, Void*)
push rbp
push r15
push r14
push r13
push r12
push rdi
push rsi
push rbx
sub rsp,68
vzeroupper
lea rbp,[rsp+0A0]
xor eax,eax
mov [rbp-40],rax
mov rbx,rcx
mov esi,edx
mov rdi,r8
lea rcx,[rbp-78]
call CORINFO_HELP_INIT_PINVOKE_FRAME
mov r14,rax
mov rcx,rsp
mov [rbp-60],rcx
mov rcx,rbp
mov [rbp-50],rcx
mov rcx,rbx
mov edx,esi
mov r8,rdi
lea r9,[rbp-40]
mov rax,7FFE915B03D8
mov [rbp-68],rax
lea rax,[M01_L00]
mov [rbp-58],rax
lea rax,[rbp-78]
mov [r14+8],rax
mov byte ptr [r14+4],0
mov rax,7FFEF11C4070
call rax
M01_L00:
mov byte ptr [r14+4],1
cmp dword ptr [7FFEF14FF778],0
je short M01_L01
call qword ptr [7FFEF14ED608]; CORINFO_HELP_STOP_FOR_GC
M01_L01:
mov rax,[rbp-70]
mov [r14+8],rax
mov rax,[rbp-40]
add rsp,68
pop rbx
pop rsi
pop rdi
pop r12
pop r13
pop r14
pop r15
pop rbp
ret
; Total bytes of code 178
Код: Выделить всё
; ConsoleAppTest.BenchmarkArray.ByRow()
push rbx
sub rsp,30
xor eax,eax
mov [rsp+28],rax
mov dword ptr [rsp+28],2710
mov dword ptr [rsp+2C],2710
lea r8,[rsp+28]
mov rcx,offset MT_System.Int32[,]
mov edx,2
call CORINFO_HELP_NEW_MDARR
xor ecx,ecx
M00_L00:
xor edx,edx
mov r8d,ecx
sub r8d,[rax+18]
mov r10d,[rax+10]
M00_L01:
mov r9d,r8d
cmp r9d,r10d
jae short M00_L02
mov r11d,[rax+14]
imul r9d,r11d
mov ebx,edx
sub ebx,[rax+1C]
cmp ebx,r11d
jae short M00_L02
add r9d,ebx
mov dword ptr [rax+r9*4+20],1
inc edx
cmp edx,2710
jl short M00_L01
inc ecx
cmp ecx,2710
jl short M00_L00
add rsp,30
pop rbx
ret
M00_L02:
call CORINFO_HELP_RNGCHKFAIL
int 3
; Total bytes of code 138
Метод
Задание
Время выполнения
Среднее
Ошибка
StdDev
Ratio
RatioSD
CacheMiisses/Op
Размер кода
Выделено
Коэффициент распределения
По строкам
.NET 10,0
.NET 10,0
139,7 мс
0,82 мс
0,69 мс
1,00
0,01
523 332
95 B
-
NA
ByColumn
.NET 10.0
.NET 10.0
569,9 мс
6,13 мс
5,12 мс
4,08
0,04
129 877 879
215 B
-
NA
По строке
.NET 9.0
.NET 9.0
129,2 мс
1,70 мс
2,15 мс
1,00
0,02
528 843
95 Б
-
NA
ByColumn
.NET 9.0
.NET 9.0
581,7 мс
7,42 мс
6,94 мс
4,51
0,09
131 969 570
215 B
-
NA
Итак, это создание массива логика дает такое воздействие, но остается вопрос - почему?
Подробнее здесь: https://stackoverflow.com/questions/798 ... g-to-net-9
Мобильная версия