Kotlin中的內(nèi)聯(lián)函數(shù)使用inline關(guān)鍵字修飾卧须,形如:
inline fun sum(x:Int, y:Int)
編譯時隐锭,會將內(nèi)聯(lián)函數(shù)中的代碼直接復(fù)制到調(diào)用處
inline有哪些優(yōu)缺點?
-
偽優(yōu)點:
運行時減少一層調(diào)用棧,提高微乎其微的一點點性能 - 缺點:增加編譯器負(fù)擔(dān)缀壤,如內(nèi)聯(lián)函數(shù)代碼很多宝剖,則會大大增加代碼量
inline使用場景
Kotlin推薦在傳入函數(shù)類型參數(shù)的函數(shù)上使用:
通過代碼看一下
[inline] fun measureTime(action : ()-> Unit) {
val start = System.currentTimeMillis()
action()
val end = System.currentTimeMillis()
println("<<<< ${end - start}ms")
}
fun main() {
measureTime { println("Long Long ago") }
}
上述代碼在編譯后:
- 使用了inline關(guān)鍵詞:measureTime方法體被直接復(fù)制到main函數(shù)中
public static final void measureTime(@NotNull Function0 action) {
int $i$f$measureTime = 0;
Intrinsics.checkParameterIsNotNull(action, "action");
long start = System.currentTimeMillis();
action.invoke();
long end = System.currentTimeMillis();
String var6 = "<<<< " + (end - start) + "ms";
boolean var7 = false;
System.out.println(var6);
}
public static final void main() {
int $i$f$measureTime = false;
long start$iv = System.currentTimeMillis();
int var3 = false;
String var4 = "Long Long ago";
boolean var5 = false;
System.out.println(var4);
long end$iv = System.currentTimeMillis();
String var9 = "<<<< " + (end$iv - start$iv) + "ms";
boolean var8 = false;
System.out.println(var9);
}
- 未使用inline關(guān)鍵詞:measureTime調(diào)用時傳入了一個額外對象null.INSTANCE
public static final void measureTime(@NotNull Function0 action) {
Intrinsics.checkParameterIsNotNull(action, "action");
long start = System.currentTimeMillis();
action.invoke();
long end = System.currentTimeMillis();
String var5 = "<<<< " + (end - start) + "ms";
boolean var6 = false;
System.out.println(var5);
}
public static final void main() {
measureTime((Function0)null.INSTANCE);
}
在不加inline的情況下病袄,measureTime若頻繁調(diào)用搂赋,則會產(chǎn)生很多不必要的額外INSTANCE赘阀。
inline真正優(yōu)勢
在傳入函數(shù)類型的函數(shù)上修飾,避免調(diào)用方創(chuàng)建不必要的額外對象
inline配合reified關(guān)鍵字脑奠,可使用泛型對象屬性
// 不加reified關(guān)鍵字基公,報錯‘cannot use T as reified parameter, use a class instead’
inline fun <T> create() {
val clazzT = T::class.java
}
// 正確寫法
inline fun <reified T> create() {
val clazzT = T::class.java
}