Megosztás a következőn keresztül:


Beágyazott függvények

A beágyazott függvények olyan függvények, amelyek közvetlenül a hívókódba integrálódnak.

Beágyazott függvények használata

Statikus típusparaméterek használatakor a típusparaméterek által paraméterezett függvényeknek beágyazottnak kell lenniük. Ez garantálja, hogy a fordító képes feloldani ezeket a típusparamétereket. Általános típusú paraméterek használata esetén nincs ilyen korlátozás.

A tagkorlátozások használatának engedélyezésén kívül a beágyazott függvények hasznosak lehetnek a kód optimalizálásában. A beágyazott függvények túlhasználata azonban azt eredményezheti, hogy a kód kevésbé lesz ellenálló a fordítóoptimalizálások változásaival és a kódtárfüggvények implementálásával szemben. Ezért kerülnie kell a beágyazott függvények használatát az optimalizáláshoz, kivéve, ha minden más optimalizálási technikát kipróbált. A függvények vagy metódusok beágyazott létrehozása néha javíthatja a teljesítményt, de ez nem mindig így van. Ezért teljesítménymérésekkel is ellenőriznie kell, hogy egy adott függvény beágyazott létrehozása valóban pozitív hatással van-e.

A inline módosító a felső szinten, a modul szintjén vagy az osztály metódusszintjén használható függvényekre.

Az alábbi példakód egy beágyazott függvényt mutat be a legfelső szinten, egy beágyazott példánymetódust és egy beágyazott statikus metódust.

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

Beágyazott függvények és típuskövetkeztetés

A jelenlét hatással van a inline típusbeli következtetésre. Ennek az az oka, hogy a beágyazott függvények statikusan feloldott típusparaméterekkel rendelkezhetnek, míg a nem beágyazott függvények nem. Az alábbi példakód egy olyan esetet mutat be, ahol inline hasznos lehet, mert statikusan feloldott típusparaméterrel rendelkező függvényt, a float konverziós operátort használ.

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

A módosító nélkül a inline típuskövetkeztetés kényszeríti a függvényt egy adott típusra, ebben az esetben int. inline A módosítóval azonban a függvény egy statikusan feloldott típusparaméterre is következtet. inline A módosítónál a típus a következőre lesz következtetve:

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

Ez azt jelenti, hogy a függvény minden olyan típust elfogad, amely támogatja a lebegőpontosra konvertálást.

InlineIfLambda

Az F#-fordító tartalmaz egy optimalizálót, amely kódrészletezést végez. Az InlineIfLambda attribútum lehetővé teszi, hogy a kód opcionálisan jelezze, hogy ha egy argumentumot lambda függvénynek határoznak meg, akkor az argumentumnak mindig beágyazottnak kell lennie a hívási helyeken. További információ: F# RFC FS-1098.

Vegyük például a következő iterateTwice függvényt egy tömb bejárásához:

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]

Ha a hívás helye a következő:

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

Ezután a kód alining és más optimalizálások után a következő lesz:

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] 

Ez az optimalizálás a lambda kifejezés méretétől függetlenül érvényesül. Ez a funkció a ciklusok regisztrációjának feloldására és a hasonló átalakítások megbízhatóbb megvalósítására is használható.

Az opt-in figyelmeztetés (/warnon:3517 vagy tulajdonság <WarnOn>3517</WarnOn>) bekapcsolható, hogy jelezze a kód azon pontjait, ahol InlineIfLambda az argumentumok nem kötődnek a lambda kifejezésekhez a hívási helyeken. Normál helyzetekben ezt a figyelmeztetést nem szabad engedélyezni. Bizonyos típusú nagy teljesítményű programozás esetén azonban hasznos lehet biztosítani, hogy az összes kód beágyazott és összesimított legyen.

Lásd még