Код: Выделить всё
using System.Runtime.InteropServices;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
[StructLayout(LayoutKind.Explicit)]
public readonly struct Counter
{
[FieldOffset(0)] public readonly int Value;
[FieldOffset(1)] public readonly byte MidByte;
public Counter(int value)
: this()
{
this.Value = value;
}
public Counter Increment(int count) // 0 counter.Increment(1);
}
public class Benchmarks
{
[Benchmark]
public Counter Benchmark1()
{
Counter c = new(0x10101);
for (int i = 0; i < 10000; ++i) {
c = c.Increment(1);
}
return c;
}
[Benchmark]
public Counter Benchmark2()
{
Counter c = new(0x10101);
for (int i = 0; i < 10000; ++i) {
++c;
}
return c;
}
}
Поскольку JIT-компилятор, скорее всего, будет использовать встроенный оператор ++, Я ожидал, что эти два теста будут работать одинаково. К моему великому удивлению и недоумению, ++c абсолютно уничтожает c = c.Increment(1):
BenchmarkDotNet v0.13.8, Windows 10 (10.0.19045.4651/22H2/2022Обновление)
Intel Core i7-11800H 11-го поколения, 2,30 ГГц, 1 ЦП, 16 логических и 8 физических ядер
.NET SDK 8.0.303
[Хост]: .NET 8.0.7 (8.0.724.31311), X64 RyuJIT AVX2
DefaultJob: .NET 8.0 .7 (8.0.724.31311), X64 RyuJIT AVX2
Метод
Среднее
Ошибка
StdDev
Размер кода
Benchmark1
18,376 США
0,1999 США
0,1870 США
68 Б
Бенчмарк2
6,564 США
0,0436 мкс
0,0408 мкс
0,0408 мкс
0,0433 нас
Benchmark2
4,595 США
0,0399 США
0,0373 нас
Подробнее здесь: https://stackoverflow.com/questions/788 ... nce-method