XNA を調べていたところ、XNA 内のVector3
クラスがプロパティではなくパブリック フィールドを使用していることがわかりました。簡単なベンチマークを試してみたところ、struct
その違いは非常に劇的であることがわかりました (2 つのベクトルを 1 億回追加すると、プロパティで 2.0 秒、フィールドで 1.4 秒かかりました)。参照型の場合、違いはそれほど大きくないように見えますが、そこにあります。
では、それはなぜでしょうか。プロパティがメソッドにコンパイルされ、メソッド呼び出しのオーバーヘッドが発生することはわかっていget_X
ますset_X
。しかし、これらの単純な getter/setterは常にJIT によってインライン化されませんか? JIT が決定したことを保証できないことは承知していますが、確かにこれは確率のリストでかなり高いですか? マシン レベルでパブリック フィールドをプロパティから分離するものは他にあるでしょうか?
そして、私が疑問に思っていることの 1 つは、自動実装されたプロパティ ( public int Foo { get; set; }
) が public フィールドよりも「優れた」OO 設計である理由は何ですか? または、より適切に言えば、これら 2 つの違いは何ですか? リフレクションを使用するとプロパティにする方が簡単であることは知っていますが、他に何かありますか? 両方の質問に対する答えは同じだと思います。
ところで:私は.NET 3.5 SP1を使用しています.NET 3.5 SP1は、構造体を含むメソッド(または構造体のメソッド、よくわかりません)がインライン化されていない問題を修正したと信じています。少なくとも使用していると思います。確かにインストールされていますが、DX10.1を持っていないことを除いて、DX10.1が必要なSP1でVista 64ビットを使用しています..
また、ええ、私はリリースビルドを実行しています:)
編集:クイックアンサーに感謝しますが、プロパティアクセスがメソッド呼び出しであることは知っていますが、おそらくインラインメソッドが直接フィールドアクセスよりも遅い理由がわからないことを示しました。
EDIT 2 :したがってstruct
、明示的な GetX() メソッドを使用する別のメソッドを作成し(Javaの日々をまったく見逃さない方法)、インライン化を無効にしたかどうかに関係なく(を介して)同じように実行した[MethodImplAttribute(MethodImplOptions.NoInlining)]
ため、結論:非静的メソッドは、構造体であってもインライン化されないようです。
JITが仮想メソッド呼び出しを最適化できる例外があると思いました。継承を認識していない構造体でこれが発生しないのはなぜですか。したがって、メソッド呼び出しは可能なメソッドを 1 つしか指すことができません。それとも、インターフェースを実装できるからですか?
パフォーマンスが重要な要素にプロパティを使用することについて本当に考えさせられるので、これはちょっと残念ですが、フィールドを使用すると汚く感じるので、自分が行っていることを C で記述したほうがよいでしょう。
EDIT 3 :まったく同じ件名に関するこの投稿を見つけました。彼の最終的な結論は、プロパティ呼び出しが最適化されてしまったということです。callvirt
また、IL にいるにもかかわらず、単純なゲッター/セッター プロパティがインライン化されることを何度も読んだと断言できます。それで私は気が狂うのですか?
EDIT 4 : Reed Copsey が以下のコメントに回答を投稿しました。
Re: Edit3 - 私の更新されたコメントを参照してください: これは x86 JIT と x64 JIT の問題だと思います。x64 の JIT はそれほど成熟していません。より多くの 64 ビット システムが毎日オンラインになるため、MS がこれを迅速に改善することを期待しています。– リード・コプシー
そして彼の答えに対する私の答え:
ありがとう、これが答えです!x86 ビルドを強制しようとしましたが、すべてのメソッドが同等に高速で、x64 よりもはるかに高速です。これは実際には非常に衝撃的です.64ビットOSで石器時代に住んでいたとは思いもしませんでした..あなたのコメントを回答に含めて、より目立つようにします. – ジュリアンR
みんな、ありがとう!