I, Inline function
1, Vấn đề
- Trước khi đọc bài viết này, mình khuyên bạn nên đọc về high-order function trước.
- High-order function gặp vấn đề là mỗi parameter có function type cần được khởi tạo bằng 1
function objecttrong memory và tạo ra runtime overhead. - Ví dụ 1:
1 | class InlineExample { |
- Khi chúng ta dùng xem nó được compile qua java code bằng
Tools > Kotlin > Show kotlin bytecode > Decompile, chúng ta sẽ thấy classInlineExample.java
1 | public final class InlineExample { |
- Ta có thể thấy
makeHighOrder()trongInlineExample.javacó 1 tham sốactioncó kiểuFunction0. - Khi nó được sử dụng ở
testAnonymous()vàtestLambada()thì sẽ tạo ra 2 objectFunction0. - Trong kotlin, chúng ta không tạo ra đối tượng nào cả ? Đây cũng là vấn đề của high-order function.
2, Inline function
- Ví dụ 2: tương tự như ví dụ 1 nhưng mình sẽ thêm
inlinekeyword vào trướcmakeHighOrder()
1 | class InlineExample { |
- Khi đó, InlineExample sẽ được compile sang java code như sau
1 | public final class InlineExample { |
- Mặc dù
makeHighOrder()vẫn được compile gần giống như cũ. - Nhưng khi gọi
testAnonymous()vàtestLambada()nhưng không tạo raFunction0nào nữa. - Có chuyện gì xảy ra khi ta sử dụng inline function ?
- Từ khóa
inlineđã copy implement của function vào nơi gọi function (call-site) đó. Do đó các call-site không tạo ra bất cứ object nào. - Chú ý:
- Inline function được dùng để tối ưu cho high-order function.
- Nếu bạn thêm
inlinevào những function thông thường sẽ không có ý nghĩa về mặt tối ưu. Android studio sẽ có warning và suggest bạn bỏinlineđi.
1 | // No performance impact. We will get warning here |
3, Giới hạn và cách dùng inline function
- Nhược điểm của inline function mà chúng ta có thể thấy ngay là chúng có thể gây ra nhiều code thừa vì implement của nó có thể dùng ở nhiều nơi.
- Inline function dùng ở đâu ?
- Chúng ta nên tránh sử dụng
inlinecho những function lớn. Chúng ta nêninlinecho những function nhỏ (vài ba dòng). - Nếu bạn xem source code của file
_Collections.ktthì bạn sẽ thấy các inline function chỉ có từ 1 đến 3 dòng.
II, Noinline
- Inline function không cho phép parameter có function type:
- Gán cho 1 local variable.
- Truyền vào trong function khác ở body.
- Ví dụ 3:
1 | private inline fun makeHighOrder( |
- Trong trường hợp này, chúng ta có thể đánh dấu
notInlinebằng từ khoánoinlinenhư ví dụ 4. - Ví dụ 4: sửa error ở ví dụ 3
1 | private inline fun makeHighOrder( |
- Khi sử dụng
noinlinecho biếnnotInlinethì khi khởi tạonotInlinelại tạo ra object trong bộ nhớ.