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# コードはとても遅いのですか? .