Vložené funkce

Vložené funkce jsou funkce , které jsou integrované přímo do volajícího kódu.

Použití vložených funkcí

Při použití parametrů statického typu musí být všechny funkce, které jsou parametrizovány podle parametrů typu, vloženy. To zaručuje, že kompilátor dokáže tyto parametry typu přeložit. Pokud používáte běžné parametry obecného typu, neexistuje takové omezení.

Kromě povolení použití omezení členů můžou být vložené funkce užitečné při optimalizaci kódu. Nadměrné využití vložených funkcí však může způsobit, že váš kód bude méně odolný vůči změnám v optimalizacích kompilátoru a implementaci funkcí knihovny. Z tohoto důvodu byste se měli vyhnout použití vložených funkcí pro optimalizaci, pokud jste nepokusili všechny ostatní techniky optimalizace. Vytvoření funkce nebo metody inline může někdy zlepšit výkon, ale to není vždy případ. Proto byste měli použít také měření výkonu k ověření, že provedení jakékoli vložené funkce má ve skutečnosti pozitivní vliv.

inline Modifikátor lze použít u funkcí na nejvyšší úrovni, na úrovni modulu nebo na úrovni metody ve třídě.

Následující příklad kódu znázorňuje vloženou funkci na nejvyšší úrovni, vloženou metodu instance a vloženou statickou metodu.

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

Vložené funkce a odvození typů

Přítomnost vliv na inline odvození typu. Důvodem je to, že vložené funkce můžou mít staticky vyřešené parametry typu, zatímco nelineové funkce nemohou. Následující příklad kódu ukazuje případ, kdy inline je užitečné, protože používáte funkci, která má staticky vyřešený parametr typu, operátor převodu float .

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

Bez modifikátoru inline vynutí odvození typu funkci, aby v tomto případě intpřevzala určitý typ . U modifikátoru inline je ale funkce také odvozena tak, aby měla staticky vyřešený parametr typu. U modifikátoru inline je typ odvozen jako následující:

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

To znamená, že funkce přijímá jakýkoli typ, který podporuje převod na plovoucí.

InlineIfLambda

Kompilátor jazyka F# obsahuje optimalizátor, který provádí vkládání kódu. Atribut InlineIfLambda umožňuje volitelně určit, že pokud je argument určen jako funkce lambda, pak by měl být tento argument vždy vložen na webech volání. Další informace najdete v tématu F# RFC FS-1098.

Představte si například následující iterateTwice funkci, která prochází polem:

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]

Pokud je web volání:

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

Potom po vložení a dalších optimalizacích se kód stane:

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] 

Tato optimalizace se použije bez ohledu na velikost zahrnutého výrazu lambda. Tuto funkci lze také použít k implementaci zrušení registrace smyčky a podobných transformací spolehlivěji.

Upozornění na vyjádření souhlasu (/warnon:3517 nebo vlastnost <WarnOn>3517</WarnOn>) je možné zapnout a vyznačit místa v kódu, kde InlineIfLambda argumenty nejsou vázány na výrazy lambda na webech volání. V normálních situacích by toto upozornění nemělo být povolené. V některých typech vysokovýkonného programování ale může být užitečné zajistit, aby byl veškerý kód vložený a zploštěný.

Viz také