Delen via


Inlinefuncties

Inlinefuncties zijn functies die rechtstreeks in de aanroepende code zijn geïntegreerd.

Inlinefuncties gebruiken

Wanneer u statische typeparameters gebruikt, moeten functies die worden geparameteriseerd op typeparameters inline zijn. Dit garandeert dat de compiler deze typeparameters kan oplossen. Wanneer u gewone algemene typeparameters gebruikt, is er geen dergelijke beperking.

Afgezien van het inschakelen van het gebruik van lidbeperkingen, kunnen inlinefuncties handig zijn bij het optimaliseren van code. Het overgebruik van inlinefuncties kan er echter toe leiden dat uw code minder bestand is tegen wijzigingen in compileroptimalisaties en de implementatie van bibliotheekfuncties. Daarom moet u het gebruik van inlinefuncties voor optimalisatie vermijden, tenzij u alle andere optimalisatietechnieken hebt geprobeerd. Het inline maken van een functie of methode kan soms de prestaties verbeteren, maar dat is niet altijd het geval. Daarom moet u ook prestatiemetingen gebruiken om te controleren of het maken van een bepaalde functie inline in feite een positief effect heeft.

De inline modifier kan worden toegepast op functies op het hoogste niveau, op moduleniveau of op methodeniveau in een klasse.

In het volgende codevoorbeeld ziet u een inlinefunctie op het hoogste niveau, een inline-exemplaarmethode en een inline statische methode.

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

Inlinefuncties en type deductie

De aanwezigheid van inline invloed is op typedeductie. Dit komt doordat inlinefuncties statisch opgeloste typeparameters kunnen hebben, terwijl niet-inlinefuncties dat niet kunnen. In het volgende codevoorbeeld ziet u een geval waarin inline dit handig is omdat u een functie gebruikt met een statisch opgeloste typeparameter, de float conversieoperator.

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

Zonder de inline wijzigingsfunctie dwingt typedeductie de functie af om een specifiek type te nemen, in dit geval int. Maar met de inline modifier wordt de functie ook afgeleid van een statisch opgeloste typeparameter. Met de inline wijzigingsfunctie wordt het type afgeleid als het volgende:

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

Dit betekent dat de functie elk type accepteert dat een conversie naar float ondersteunt.

InlineIfLambda

De F#-compiler bevat een optimalisatieprogramma waarmee code wordt geïnlind. Met InlineIfLambda het kenmerk kan eventueel worden aangegeven dat, als een argument wordt bepaald als een lambda-functie, dat argument altijd inline moet zijn op oproepsites. Zie F# RFC FS-1098 voor meer informatie.

Denk bijvoorbeeld aan de volgende iterateTwice functie om een matrix te doorlopen:

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]

Als de oproepsite het volgende is:

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

Daarna wordt de code na het inlijnen en andere optimalisaties:

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] 

Deze optimalisatie wordt toegepast, ongeacht de grootte van de lambda-expressie. Deze functie kan ook worden gebruikt om lus uitschrijven en vergelijkbare transformaties betrouwbaarder te implementeren.

Een opt-in-waarschuwing (/warnon:3517 of eigenschap <WarnOn>3517</WarnOn>) kan worden ingeschakeld om plaatsen in uw code aan te geven waarbij InlineIfLambda argumenten niet zijn gebonden aan lambda-expressies op oproepsites. In normale situaties mag deze waarschuwing niet worden ingeschakeld. In bepaalde soorten programmeren met hoge prestaties kan het echter handig zijn om ervoor te zorgen dat alle code inline en afgevlakt is.

Zie ook