19

私は重いCPUバウンドの問題に取り組んでいます。inlineキーワードを使用すると、パフォーマンスが大幅に向上します。カスタム キー Comparer を渡す標準の .net ライブラリから辞書を作成します。以下のコードとタイミングの結果を参照してください。

https://gist.github.com/4409734

Eq_cmp の inline キーワードなし

> perf_run 10000000 ;;
Real: 00:00:11.039, CPU: 00:00:11.029, GC gen0: 771, gen1: 3, gen2: 1
val it : unit = ()

Eq_cmp で inline キーワードを使用する

perf_run 10000000 ;;
Real: 00:00:01.319, CPU: 00:00:01.388, GC gen0: 1, gen1: 1, gen2: 1
val it : unit = ()
> 

また、インライン コードと非インライン コードでは、Gen 0 GC の量に大きな違いがあることにも気付きました。

このような大きな違いがある理由を誰か説明できますか?

4

2 に答える 2

18

inlineキーワードを追加すると、パフォーマンスが 3 倍に向上し、自分のマシンで動作を再現できます。

ILSpyで 2 つのバージョンを並べて逆コンパイルすると、ほぼ同一の C# コードが得られます。顕著な違いは、次の 2 つの等価テストにあります。

// Version without inline
bool IEqualityComparer<Program.Pair<a>>.System-Collections-Generic-IEqualityComparer(Program.Pair<a> x, Program.Pair<a> y)
{
    a v@ = x.v@;
    a v@2 = y.v@;
    if (LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<a>(v@, v@2))
    {
        a w@ = x.w@;
        a w@2 = y.w@;
        return LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<a>(w@, w@2);
    }
    return false;
}

// Version with inline
bool IEqualityComparer<Program.Pair<int>>.System-Collections-Generic-IEqualityComparer(Program.Pair<int> x, Program.Pair<int> y)
{
    int v@ = x.v@;
    int v@2 = y.v@;
    if (v@ == v@2)
    {
        int w@ = x.w@;
        int w@2 = y.w@;
        return w@ == w@2;
    }
    return false;
}

一般的な等価性は、特殊化されたバージョンよりも効率が大幅に低下します。

また、インライン コードと非インライン コードでは、Gen 0 GC の量に大きな違いがあることにも気付きました。

このような大きな違いがある理由を誰か説明できますか?

F# ソース コードGenericEqualityIntrinsicの関数を見てみましょう。

let rec GenericEqualityIntrinsic (x : 'T) (y : 'T) : bool = 
    fsEqualityComparer.Equals((box x), (box y))

引数のボクシングを行います。これは、最初の例でかなりの量のガベージを説明しています。GC が頻繁に使用されると、計算が大幅に遅くなります。2 番目の例 ( を使用) では、が structinlineの場合、ガベージはほとんど生成されません。Pair

つまりinline、呼び出しサイトで特殊なバージョンが使用された場合のキーワードの予期される動作です。私の提案は、常に同じベンチマークでコードを最適化して測定することです。

非常によく似たスレッドに興味があるかもしれませんなぜこの F# コードはとても遅いのですか? .

于 2012-12-29T23:49:44.417 に答える
16

型特化

がなければinline、非常に非効率的な一般的な比較を使用しています。ではinline、一般性が取り除かれ、int比較が直接使用されます。

于 2012-12-31T17:38:58.787 に答える