2023/01/30(Mon) 15:41:14 編集(投稿者)
https://sharplab.io で、簡単な検証用ソースのアセンブリコードを比較してみました。
----------------
Imports System
Imports System.Diagnostics
Imports System.Runtime.CompilerServices
Module Module1
Public Structure PointF_3DF
Public X As Integer
Public Y As Integer
Public Z As Integer
Public Function Sum() As Integer
Return X + Y + Z
End Function
End Structure
Public Structure PointF_3DP
Property X As Integer
Property Y As Integer
Property Z As Integer
Public Function Sum() As Integer
Return X + Y + Z
End Function
<MethodImpl(MethodImplOptions.AggressiveInlining)>
Public Function Sum2() As Integer
Return X + Y + Z
End Function
End Structure
Sub Calc1()
Dim v = Create3DF()
Console.WriteLine(v.Sum())
End Sub
Sub Calc2()
Dim v = Create3DP()
Console.WriteLine(v.Sum())
End Sub
Sub Calc3()
Dim v = Create3DP()
Console.WriteLine(v.Sum2())
End Sub
Function Create3DF() As PointF_3DF
Static r As New Random
Const Max = 100
Return New PointF_3DF() With {.X = r.Next(1, Max), .Y = r.Next(1, Max), .Z = r.Next(1, Max)}
End Function
Function Create3DP() As PointF_3DP
Static r As New Random
Const Max = 100
Return New PointF_3DP() With {.X = r.Next(1, Max), .Y = r.Next(1, Max), .Z = r.Next(1, Max)}
End Function
End Module
----------------
[x64 Release]
; Core CLR 7.0.22.51805 on x64
Module1.Calc1()
L0000: sub rsp, 0x38
L0004: xor eax, eax
L0006: mov [rsp+0x28], rax
L000b: mov [rsp+0x30], rax
L0010: lea rcx, [rsp+0x28]
L0015: call 0x00007ff9b0ee0048
L001a: mov ecx, [rsp+0x28]
L001e: add ecx, [rsp+0x2c]
L0022: jo short L003c
L0024: add ecx, [rsp+0x30]
L0028: jo short L003c
L002a: mov rax, 0x7ff9644a9b70
L0034: call qword ptr [rax]
L0036: nop
L0037: add rsp, 0x38
L003b: ret
L003c: call 0x00007ff9c30c8710
L0041: int3
Module1.Calc2()
L0000: sub rsp, 0x38
L0004: xor eax, eax
L0006: mov [rsp+0x28], rax
L000b: mov [rsp+0x30], rax
L0010: lea rcx, [rsp+0x28]
L0015: call 0x00007ff9b0ee0060
L001a: mov ecx, [rsp+0x28]
L001e: add ecx, [rsp+0x2c]
L0022: jo short L003c
L0024: add ecx, [rsp+0x30]
L0028: jo short L003c
L002a: mov rax, 0x7ff9644a9b70
L0034: call qword ptr [rax]
L0036: nop
L0037: add rsp, 0x38
L003b: ret
L003c: call 0x00007ff9c30c8710
L0041: int3
Module1.Calc3()
L0000: sub rsp, 0x38
L0004: xor eax, eax
L0006: mov [rsp+0x28], rax
L000b: mov [rsp+0x30], rax
L0010: lea rcx, [rsp+0x28]
L0015: call 0x00007ff9b0ee0060
L001a: mov ecx, [rsp+0x28]
L001e: add ecx, [rsp+0x2c]
L0022: jo short L003c
L0024: add ecx, [rsp+0x30]
L0028: jo short L003c
L002a: mov rax, 0x7ff9644a9b70
L0034: call qword ptr [rax]
L0036: nop
L0037: add rsp, 0x38
L003b: ret
L003c: call 0x00007ff9c30c8710
L0041: int3
[.NET Framework x64 Release]
; Desktop CLR 4.8.4526.0 on amd64
Module1.Calc1()
L0000: sub rsp, 0x38
L0004: xor eax, eax
L0006: mov [rsp+0x28], rax
L000b: mov [rsp+0x30], rax
L0010: lea rcx, [rsp+0x28]
L0015: call Module1.Create3DF()
L001a: mov ecx, [rsp+0x28]
L001e: add ecx, [rsp+0x2c]
L0022: jo L0035
L0024: add ecx, [rsp+0x30]
L0028: jo L0035
L002a: call System.Console.WriteLine(Int32)
L002f: nop
L0030: add rsp, 0x38
L0034: ret
L0035: call 0x7ff9e6ae9090
L003a: int3
Module1.Calc2()
L0000: sub rsp, 0x38
L0004: xor eax, eax
L0006: mov [rsp+0x28], rax
L000b: mov [rsp+0x30], rax
L0010: lea rcx, [rsp+0x28]
L0015: call Module1.Create3DP()
L001a: lea rcx, [rsp+0x28]
L001f: call Module1+PointF_3DP.Sum()
L0024: mov ecx, eax
L0026: call System.Console.WriteLine(Int32)
L002b: nop
L002c: add rsp, 0x38
L0030: ret
Module1.Calc3()
L0000: sub rsp, 0x38
L0004: xor eax, eax
L0006: mov [rsp+0x28], rax
L000b: mov [rsp+0x30], rax
L0010: lea rcx, [rsp+0x28]
L0015: call Module1.Create3DP()
L001a: mov ecx, [rsp+0x28]
L001e: add ecx, [rsp+0x2c]
L0022: jo L0035
L0024: add ecx, [rsp+0x30]
L0028: jo L0035
L002a: call System.Console.WriteLine(Int32)
L002f: nop
L0030: add rsp, 0x38
L0034: ret
L0035: call 0x7ff9e6ae9090
L003a: int3
.NET Frameworkだと、プロパティがインライン展開されていないですね。
その場合でも、AggressiveInlining指定で同じようなコードが出力されました。
このように、最適化はフレームワーク等の条件で変化する可能性もあるので、
動作環境や計測方法のソースを記述した方がよろしいかと思います。
理論上は遅くなりそうなソースでも、
実際は最適化によって殆ど変わらないというケースも十分ありえます。