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.