次の方法で共有


インライン関数

インライン関数 は、呼び出し元のコードに直接統合される関数です。

インライン関数の使用

静的型パラメーターを使用する場合、型パラメーターによってパラメーター化されるすべての関数はインラインである必要があります。 これにより、コンパイラはこれらの型パラメーターを解決できることを保証します。 通常のジェネリック型パラメーターを使用する場合、このような制限はありません。

メンバー制約の使用を有効にする以外に、インライン関数はコードの最適化に役立ちます。 ただし、インライン関数が過剰に使用されると、コンパイラの最適化やライブラリ関数の実装の変更に対するコードの耐性が低下する可能性があります。 このため、他のすべての最適化手法を試していない限り、最適化にインライン関数を使用しないようにする必要があります。 関数またはメソッドをインラインで作成すると、パフォーマンスが向上することがありますが、必ずしもそうであるとは限りません。 したがって、パフォーマンス測定を使用して、特定の関数をインラインにすることは実際には肯定的な効果を持っていることを確認する必要があります。

inline修飾子は、最上位レベル、モジュール レベル、またはクラスのメソッド レベルの関数に適用できます。

次のコード例は、最上位レベルのインライン関数、インライン インスタンス メソッド、インライン静的メソッドを示しています。

let inline increment x = x + 1
type WrapInt32() =
    member inline this.incrementByOne(x) = x + 1
    static member inline Increment(x) = x + 1

インライン関数と型推論

inlineが存在すると、型の推論に影響します。 これは、インライン関数は静的に解決される型パラメーターを持つことができますが、インライン以外の関数では解決できないためです。 次のコード例は、静的に解決された型パラメーターであるfloat変換演算子を持つ関数を使用しているため、inlineが役立つケースを示しています。

let inline printAsFloatingPoint number =
    printfn "%f" (float number)

inline修飾子を指定しない場合、型推論では、関数が特定の型を受け取るように強制されます(この場合はint)。 ただし、 inline 修飾子では、静的に解決された型パラメーターを持つ関数も推論されます。 inline修飾子では、型は次のように推論されます。

^a -> unit when ^a : (static member op_Explicit : ^a -> float)

これは、関数が float への変換をサポートする任意の型を受け入れることを意味します。

InlineIfLambda

F# コンパイラには、コードのインライン化を実行するオプティマイザーが含まれています。 InlineIfLambda属性を使用すると、必要に応じて、引数がラムダ関数であると判断された場合は、その引数自体を呼び出しサイトで常にインライン化する必要があることをコードで示すことができます。 詳細については、 F# RFC FS-1098 を参照してください。

たとえば、次の iterateTwice 関数を使用して配列を走査するとします。

let inline iterateTwice ([<InlineIfLambda>] action) (array: 'T[]) =
    for i = 0 to array.Length-1 do
        action array[i]
    for i = 0 to array.Length-1 do
        action array[i]

呼び出しサイトが次の場合:

let arr = [| 1.. 100 |]
let mutable sum = 0
arr  |> iterateTwice (fun x ->
    sum <- sum + x)

その後、インライン化やその他の最適化の後、コードは次のようになります。

let arr = [| 1..100 |]
let mutable sum = 0
for i = 0 to arr.Length - 1 do
    sum <- sum + arr[i] 
for i = 0 to arr.Length - 1 do
    sum <- sum + arr[i] 

この最適化は、関係するラムダ式のサイズに関係なく適用されます。 この機能を使用して、ループの展開と同様の変換をより確実に実装することもできます。

オプトイン警告 (/warnon:3517 またはプロパティ <WarnOn>3517</WarnOn>) をオンにすると、呼び出しサイトで InlineIfLambda 引数がラムダ式にバインドされていないコード内の場所を示すことができます。 通常の状況では、この警告を有効にしないでください。 ただし、特定の種類の高パフォーマンス プログラミングでは、すべてのコードをインライン化してフラット化すると便利です。

こちらも参照ください