292

C#で「インライン関数」をどのように実行しますか?私はその概念を理解していないと思います。それらは匿名メソッドのようなものですか?ラムダ関数のように?

注:答えは、関数をインライン化する機能、つまり「関数呼び出しサイトを呼び出し先の本体に置き換える手動またはコンパイラーの最適化」をほぼ完全に扱っています。匿名(別名ラムダ)関数に興味がある場合は、 @ jalfの回答を参照するか、誰もが話し続けるこの「ラムダ」とは何ですか?

4

14 に答える 14

417

最後に、.NET 4.5 では、CLR により、値を使用して1つのメソッドのインライン化をヒント/提案することができMethodImplOptions.AggressiveInliningます。Mono のトランク (本日コミット) でも利用できます。

// The full attribute usage is in mscorlib.dll,
// so should not need to include extra references
using System.Runtime.CompilerServices; 

...

[MethodImpl(MethodImplOptions.AggressiveInlining)]
void MyMethod(...)

1 . 以前はここで「力」が使用されていました。私は用語を明確にしようとします。コメントとドキュメントのように、The method should be inlined if possible.特に Mono (オープン) を考慮すると、インライン化またはより一般的なもの (仮想関数など) を考慮すると、mono 固有の技術的な制限がいくつかあります。全体として、はい、これはコンパイラへのヒントですが、それが求められたものだと思います。

于 2012-01-05T16:38:01.093 に答える
61

更新: konrad.kruczynskiの回答によると、以下は 4.0 までの .NET のバージョンに当てはまります。

MethodImplAttribute クラスを使用して、メソッドがインライン化されないようにすることができます...

[MethodImpl(MethodImplOptions.NoInlining)]
void SomeMethod()
{
    // ...
}

...しかし、反対のことをして強制的にインライン化する方法はありません。

于 2010-01-16T22:48:59.897 に答える
2

「これらのものをそのままにして、コンパイラに作業を任せるのが最善です。」(Cody Brocious)は完全に無愛想です。私は高性能ゲームコードを20年間プログラミングしてきましたが、どのコードをインライン化(​​関数)するかを知るのに「十分に賢い」コンパイラーに出会ったことはありません。c#に「インライン」ステートメントを含めると便利です。実際のところ、コンパイラには、「インライン」ヒントなしで常にインライン化するかどうかを決定するために必要なすべての情報がありません。関数が小さい(アクセサー)場合は、自動的にインライン化される可能性がありますが、数行のコードの場合はどうでしょうか。意味がありません。コンパイラには知る方法がありません。最適化されたコード(アルゴリズムを超えて)をコンパイラに任せることはできません。

于 2011-03-04T22:21:07.293 に答える
2

コードを強制的にインライン化したい場合があります。

たとえば、非常に反復的なブロック内で多数の決定が行われる複雑なルーチンがあり、それらの決定により、実行されるアクションが類似しているがわずかに異なる場合があります。たとえば、高速言語の文法基準と意味基準に従って単語をソートする場合のように、ソートアルゴリズムが関連のないさまざまな基準に従って要素をソートする複雑な (DB 駆動ではない) ソート比較子を考えてみましょう。認識システム。ソース コードの可読性とモジュール性を維持するために、これらのアクションを処理するヘルパー関数を作成する傾向があります。

これらのヘルパー関数はインライン化する必要があることを知っています。これは、人間が理解する必要がない場合のコードの記述方法であるためです。この場合、関数呼び出しのオーバーヘッドがないことを確実にしたいと思います。

于 2010-06-29T20:04:56.580 に答える
1

この質問はC#に関するものであることを知っています。ただし、F# を使用して .NET でインライン関数を記述できます。参照: F# での `inline` の使用

于 2012-12-22T12:45:43.627 に答える
0

アセンブリが ngen 化される場合は、TargetedPatchingOptOut を確認することをお勧めします。これは、ngen がメソッドをインライン化するかどうかを決定するのに役立ちます。MSDN リファレンス

ただし、これは命令的なコマンドではなく、最適化するための宣言的なヒントにすぎません。

于 2011-11-22T19:42:07.113 に答える
0

いいえ、C# にはそのような構造はありませんが、.NET JIT コンパイラは、JIT 時にインライン関数呼び出しを行うことを決定できます。しかし、実際にそのような最適化を行っているかどうかはわかりません。
(そうすべきだと思います:-))

于 2009-01-23T17:43:14.667 に答える
-8

C# は、Python のような動的言語のようにインライン メソッド (または関数) をサポートしていません。ただし、匿名メソッドとラムダは、以下の例のように、包含メソッド内の変数にアクセスする必要がある場合など、同様の目的で使用できます。

static void Main(string[] args)
{
    int a = 1;

    Action inline = () => a++;
    inline();
    //here a = 2
}
于 2009-01-23T17:44:33.477 に答える