Bagikan melalui


Fungsi Sebaris

Fungsi sebaris adalah fungsi yang terintegrasi langsung ke dalam kode panggilan.

Menggunakan Fungsi Sebaris

Saat Anda menggunakan parameter jenis statis, fungsi apa pun yang diparameterkan menurut parameter jenis harus sebaris. Ini menjamin bahwa pengkompilasi dapat menyelesaikan parameter jenis ini. Ketika Anda menggunakan parameter jenis generik biasa, tidak ada batasan seperti itu.

Selain mengaktifkan penggunaan batasan anggota, fungsi sebaris dapat membantu dalam mengoptimalkan kode. Namun, penggunaan fungsi sebaris yang berlebihan dapat menyebabkan kode Anda kurang tahan terhadap perubahan pengoptimalan kompilator dan implementasi fungsi pustaka. Untuk alasan ini, Anda harus menghindari penggunaan fungsi sebaris untuk pengoptimalan kecuali Anda telah mencoba semua teknik pengoptimalan lainnya. Membuat fungsi atau metode sebaris terkadang dapat meningkatkan performa, tetapi itu tidak selalu terjadi. Oleh karena itu, Anda juga harus menggunakan pengukuran performa untuk memverifikasi bahwa membuat fungsi tertentu sebaris sebenarnya memiliki efek positif.

Pengubah inline dapat diterapkan ke fungsi di tingkat atas, di tingkat modul, atau pada tingkat metode di kelas.

Contoh kode berikut mengilustrasikan fungsi sebaris di tingkat atas, metode instans sebaris, dan metode statis sebaris.

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

Fungsi Sebaris dan Inferensi Jenis

Kehadiran inline mempengaruhi inferensi jenis. Ini karena fungsi sebaris dapat memiliki parameter jenis yang diselesaikan secara statis, sedangkan fungsi non-sebaris tidak dapat. Contoh kode berikut menunjukkan kasus di mana inline berguna karena Anda menggunakan fungsi yang memiliki parameter jenis yang diselesaikan secara statis, float operator konversi.

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

Tanpa pengubah inline , inferensi jenis memaksa fungsi untuk mengambil jenis tertentu, dalam hal intini . Tetapi dengan pengubah inline , fungsi juga disimpulkan untuk memiliki parameter jenis yang diselesaikan secara statis. Dengan pengubah inline , jenis disimpulkan sebagai berikut:

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

Ini berarti bahwa fungsi menerima jenis apa pun yang mendukung konversi ke float.

InlineIfLambda

Pengkompilasi F# mencakup pengoptimal yang melakukan inlining kode. Atribut InlineIfLambda memungkinkan kode untuk secara opsional menunjukkan bahwa, jika argumen ditentukan sebagai fungsi lambda, maka argumen itu harus selalu di-inlin di situs panggilan. Untuk informasi selengkapnya, lihat F# RFC FS-1098.

Misalnya, pertimbangkan fungsi berikut iterateTwice untuk melintasi array:

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]

Jika situs panggilan adalah:

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

Kemudian setelah inlining dan pengoptimalan lainnya, kode menjadi:

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] 

Pengoptimalan ini diterapkan terlepas dari ukuran ekspresi lambda yang terlibat. Fitur ini juga dapat digunakan untuk mengimplementasikan unrolling loop dan transformasi serupa dengan lebih andal.

Peringatan keikutsertaan (/warnon:3517 atau properti <WarnOn>3517</WarnOn>) dapat diaktifkan untuk menunjukkan tempat dalam kode Anda di mana InlineIfLambda argumen tidak terikat pada ekspresi lambda di situs panggilan. Dalam situasi normal, peringatan ini tidak boleh diaktifkan. Namun, dalam jenis pemrograman berkinerja tinggi tertentu, dapat berguna untuk memastikan semua kode sebaris dan diratakan.

Lihat juga