Я пытаюсь добавить некоторые выводы, хотя пока не отвечаю.BenchmarkDotNet показывал мне те же результаты, что и вы.
Сначала я провел некоторые профилирования в VS с инструментами, чтобы показать, что нет никаких сомнений в том, что само сложение потребляет время и приносит большую разницу.
*Выполнено 1004 * результатов выполнения 64-битного кода:
против.32 бита:
код IL этих двух строк:
// value += value2;
IL_0059: ldloc.0
IL_005a: ldloc.1
IL_005b: call valuetype UserQuery/Vector2_A UserQuery/Vector2_A::op_Addition(valuetype UserQuery/Vector2_A, valuetype UserQuery/Vector2_A)
IL_0060: stloc.0
// value3 += value4;
IL_0061: ldloc.2
IL_0062: ldloc.3
IL_0063: call valuetype UserQuery/Vector3_A UserQuery/Vector3_A::op_Addition(valuetype UserQuery/Vector3_A, valuetype UserQuery/Vector3_A)
IL_0068: stloc.2
, за которыми следуют 2 метода операции добавления, 2 dim:
.method public hidebysig specialname static
valuetype UserQuery/Vector2_A op_Addition (
valuetype UserQuery/Vector2_A value1,
valuetype UserQuery/Vector2_A value2
) cil managed
{
// Method begins at RVA 0x2100
// Code size 37 (0x25)
.maxstack 3
.locals init (
[0] valuetype UserQuery/Vector2_A
)
// (no C# code)
IL_0000: nop
// return new Vector2_A(value1.X + value2.X, value1.Y + value2.Y);
IL_0001: ldarg.0
IL_0002: ldfld float32 UserQuery/Vector2_A::X
IL_0007: ldarg.1
IL_0008: ldfld float32 UserQuery/Vector2_A::X
IL_000d: add
IL_000e: ldarg.0
IL_000f: ldfld float32 UserQuery/Vector2_A::Y
IL_0014: ldarg.1
IL_0015: ldfld float32 UserQuery/Vector2_A::Y
IL_001a: add
IL_001b: newobj instance void UserQuery/Vector2_A::.ctor(float32, float32)
IL_0020: stloc.0
// (no C# code)
IL_0021: br.s IL_0023
IL_0023: ldloc.0
IL_0024: ret
} // end of method Vector2_A::op_Addition
и 3-мерное:
.method public hidebysig specialname static
valuetype UserQuery/Vector3_A op_Addition (
valuetype UserQuery/Vector3_A value1,
valuetype UserQuery/Vector3_A value2
) cil managed
{
// Method begins at RVA 0x214c
// Code size 50 (0x32)
.maxstack 4
.locals init (
[0] valuetype UserQuery/Vector3_A
)
// (no C# code)
IL_0000: nop
// return new Vector3_A(value1.X + value2.X, value1.Y + value2.Y, value1.Z + value2.Z);
IL_0001: ldarg.0
IL_0002: ldfld float32 UserQuery/Vector3_A::X
IL_0007: ldarg.1
IL_0008: ldfld float32 UserQuery/Vector3_A::X
IL_000d: add
IL_000e: ldarg.0
IL_000f: ldfld float32 UserQuery/Vector3_A::Y
IL_0014: ldarg.1
IL_0015: ldfld float32 UserQuery/Vector3_A::Y
IL_001a: add
IL_001b: ldarg.0
IL_001c: ldfld float32 UserQuery/Vector3_A::Z
IL_0021: ldarg.1
IL_0022: ldfld float32 UserQuery/Vector3_A::Z
IL_0027: add
IL_0028: newobj instance void UserQuery/Vector3_A::.ctor(float32, float32, float32)
IL_002d: stloc.0
// (no C# code)
IL_002e: br.s IL_0030
IL_0030: ldloc.0
IL_0031: ret
} // end of method Vector3_A::op_Addition
, если честно, остальное просто догадка, что метод 3 dim add имеет некоторые преимущества с mem / stackвыравнивание, как говорится, размер кода 0x32 против 0x25 и maxstack 4 против 3.
Проверка результатов ассемблера x64 в RjuJIT позволила бы мне исчерпать талант.Может быть стоит за это пинговать JIT экспертов MS?