簡體   English   中英

與匿名內部類相比,Kotlin lambda的表現如何?

[英]How does Kotlin lambda perform compared to Anonymous inner class?

Android Studio建議用lambda代替匿名內部類。

titleTextView.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View?) {
        Log.d("MY_TAG", "textView clicked in anonymous inner class")
    }
})

反編譯的Java代碼:

var10000 = this.titleTextView;
if (this.titleTextView == null) {
    Intrinsics.throwUninitializedPropertyAccessException("titleTextView");
}

var10000.setOnClickListener((OnClickListener)(new OnClickListener() {
    public void onClick(@Nullable View v) {
        Log.d("MY_TAG", "textView clicked in anonymous inner class");
    }
}));

在使用lambda之前,為避免為設置了OnClickListener的每個視圖創建新對象,最好讓Activity / Fragment實現View.OnClickListener接口或使用Butterknife@OnClick批注。

如下所示的lambda的性能會有何不同?

titleTextView.setOnClickListener { Log.d("MY_TAG", "textView clicked in lambda") }

反編譯的Java代碼:

TextView var10000 = this.titleTextView;
if (this.titleTextView == null) {
    Intrinsics.throwUninitializedPropertyAccessException("titleTextView");
}

var10000.setOnClickListener((OnClickListener)null.INSTANCE);

在使用lambda的情況下,在反編譯的代碼Log.d("MY_TAG", "textView clicked in lambda")不到Log.d("MY_TAG", "textView clicked in lambda")

Lambda的性能至少與創建匿名內部類一樣好。

  • 如果未捕獲任何引用,則編譯器會將其用作優化措施所使用的任何類中的一個。 這就是您的情況,因為偵聽器的內容沒有引用lambda之外的任何內容。 (此單例實例是null.INSTANCE試圖引用的實例,反編譯器在解析為lambda生成的類的名稱時遇到了麻煩。)因此,在這種情況下,lambda的開銷僅為1個對象分配。

  • 如果您的lambda確實捕獲到某些東西,例如:

     val random = Random().nextInt() titleTextView.setOnClickListener { Log.d("MY_TAG", "textView clicked in lambda, random value was $random") } 

    ...然后,每當您設置偵聽器時,都將必須分配一個新實例,因為這些實例必須存儲對變量的引用,每次創建變量時引用可能會有所不同。 在這種情況下,您獲得的對象分配與運行lambda的方法的次數一樣多。請注意,如果僅在安裝過程中完成此操作(如onCreate ,則這也將意味着僅分配1個對象。

這樣您可能會得到:

  • 如果您的偵聽器是您現有類的方法(片段或活動),則額外分配0個。
  • 如果您使用不捕獲任何內容的lambda,則額外分配1個。
  • 如果您使用捕獲了某些內容的lambda,則N個額外的分配,N為您運行代碼使用lambda的次數,如果僅在初始化期間,則為1。
  • 如果使用匿名內部類,則沒有N個額外的分配,因為那里沒有針對非捕獲類的優化。 同樣,在很多情況下,這實際上可能是1。

即使在現有類中使用方法意味着增加0個分配,我也不會采用這種方法來提高性能-任何收益都可能完全不明顯。 而是選擇對您而言更具可讀性和可維護性的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM