C#が手動のインラインメソッドをサポートしない理由はありますか?そして、オプションのパラメーターはどうですか?
-
06-07-2019 - |
質問
そのための設計上の理由はありますか(多重継承を放棄した理由など)?
またはそれだけでは十分ではなかったのですか?
メソッド内のオプションパラメータにも同じ質問が当てはまります...これはすでにvb.netの最初のバージョンにありました...したがって、MSがオプションパラメータを許可しない怠は確かにありません。おそらくアーキテクチャの決定。 C#4にはそれが含まれるからです。
決定の内容とその理由を断念した人は誰ですか?
編集:
あなたは私を完全に理解していなかったのかもしれません。 私は最近、いくつかの方法が文字通り毎秒何百万回も使用される計算プログラム(最後の桁までの任意のサイズの数値をサポート)に取り組んでいます。
Add(int num)というメソッドがあるとします。このメソッドは、パラメーターとして1を使用して( Add(1);
)頻繁に使用されます。特に特別なメソッドを実装するために。そして、オーバーロードを意味するわけではありません-AddOneという新しいメソッドを作成し、Addメソッドをその中にコピーします。ただし、 num
を使用する代わりに 1
を作成します。これは恐ろしく奇妙に思えるかもしれませんが、実際には高速です。
(見苦しい限り)
C#が手動のインラインをサポートしていないのはなぜだろうと思いました。 こちら。
ありがとう。 (そして、なぜ私に投票を拒否したのですか:S)
編集2:
これを追加するかどうかを自問しました。このようなプロジェクトにドットネットなどのプラットフォームを選択することの奇妙さ(および欠点)には非常に精通していますが、ドットネットの最適化はあなたが考えるよりも重要だと思います...特にCPUなどの機能など
解決
質問の一部に回答するには、Eric Gunnersonのブログ投稿を参照してください: C#に「インライン」キーワードがないのはなぜですか?
彼の投稿からの引用:
C#の場合、インライン化はJITで行われます レベル、およびJITは一般的に 適切な決定。
編集:オプションパラメータの遅延サポートの理由はわかりませんが、「あきらめた」と言います。他の言語が提供するものに対する私たちの期待に基づいて、彼らがそれを実装することが期待されているかのように聞こえます。優先順位のリストでは高くなく、各バージョンの特定の機能を公開する期限があったと思います。特にメソッドのオーバーロードが利用可能な代替手段だったため、これはおそらく今まで重要性が高まっていませんでした。一方、ジェネリック(2.0)、およびLINQを可能にする機能など(3.0)を得ました。言語の進歩に満足しています。前述の機能は、オプションパラメータのサポートを早期に取得するよりも重要です。
他のヒント
手動インライン化はほとんど役に立ちません。 JITコンパイラーは、ネイティブコードのコンパイル中に適切な場合にメソッドをインライン化します。ほとんどすべての場合、JITコンパイラーはプログラマーよりも適切かどうかを推測するのに優れていると思います。
オプションのパラメータについては、以前のバージョンに存在しなかった理由がわかりません。とはいえ、C#4に存在するのは好ましくありません。パラメーターが消費アセンブリに焼き付けられ、DLLの標準値を変更して消費する場合は再コンパイルする必要があるため、やや有害だと考えられるためです。新しいアセンブリを使用するアセンブリ。
編集:
インライン化に関する追加情報。 JITコンパイラーにメソッド呼び出しのインライン化を強制することはできませんが、メソッド呼び出しをインライン化しないように強制することはできます。これには、System.Runtime.CompilerServices.MethodImplAttributeを次のように使用します。
internal static class MyClass
{
[System.Runtime.CompilerServices.MethodImplAttribute(MethodImplOptions.NoInlining)]
private static void MyMethod()
{
//Powerful, magical code
}
//Other code
}
私の知識による推測:以前のバージョンのC#にオプションのパラメーターがなかった理由は、C ++でのそれらの使用経験が悪いためです。表面上は十分に単純に見えますが、いくつかの厄介なコーナーケースがあります。 Herb Sutterの本の1つでこれについて詳しく説明していると思います。一般に、 virtual
メソッドをオーバーライドする必要があります。 Maximilian は、.NETコーナーケースの1つを彼の回答で言及しています。
また、手動で複数のオーバーロードを記述することで、それらをほとんどなくすことができます。クラスの作成者にとってはあまりいいことではないかもしれませんが、クライアントはオーバーロードとオプションのパラメーターの違いにほとんど気づかないでしょう。
では、これらすべての年月が過ぎていたのに、なぜC#4.0はそれらを追加したのですか? 1)VB.NETとのパリティが改善され、2)COMとの相互運用が容易になりました。
最近、計算プログラム(最後の桁まで、任意のサイズの数値をサポート)に取り組んでいます。このプログラムでは、文字通り1秒間に数百万回使用されます。
次に、間違った言語を選択しました。実際にコードのプロファイルを作成したと思いますか(右?)また、高性能のネイティブbigintライブラリを使用しており、独自のライブラリを作成していませんか?
それが本当なら、.NETを使用しないでください。部分的な専門化の速度を上げることができると思われる場合は、Haskell、C、Fortran、またはそれを自動的に行う他の言語に移動するか、手動でインライン化を公開できます。
Add(1)
が本当に重要な場合、ヒープの割り当ても重要です。
しかし、プロファイラーがあなたに伝えることができるものを本当に見るべきです...
C#は4.0でそれらを追加しました: http:/ /msdn.microsoft.com/en-us/library/dd264739(VS.100).aspx
最初から行われなかった理由については、おそらくメソッドのオーバーロードがより柔軟性を与えたと感じたためです。オーバーロードを使用すると、使用している他のパラメーターに基づいて複数の「デフォルト」を指定できます。また、それほど多くの構文ではありません。
C ++のような言語でも、何かをインライン化しても、それが発生することは保証されません。コンパイラーへのヒントです。 コンパイラーはヒントを取るか、独自の操作を行うことができます。 。
C#は、生成されたアセンブリコードから(IL + JITを介して)削除される別のステップであるため、何かがインラインになることを保証することはさらに難しくなります。さらに、JITのx86 + x64実装の動作が異なるなどの問題があります。
Javaにはインラインキーワードも含まれていません。より優れたJava JITは仮想メソッドでもインライン化でき、 private や final などのキーワードを使用しても違いはありません(以前は使用されていましたが、これは古代の歴史です)。