【轉】Kotlin的inline內聯函數

来源:https://www.cnblogs.com/MillerKevin/archive/2019/08/16/11364833.html
-Advertisement-
Play Games

原文鏈接:https://blog.csdn.net/Jaden_hool/article/details/78437947 方法調用流程 調用一個方法是一個壓棧和出棧的過程,調用方法時將棧針壓入方法棧,然後執行方法體,方法結束時將棧針出棧,這個壓棧和出棧的過程會耗費資源,這個過程中傳遞形參也會耗費 ...


原文鏈接:https://blog.csdn.net/Jaden_hool/article/details/78437947

方法調用流程

調用一個方法是一個壓棧和出棧的過程,調用方法時將棧針壓入方法棧,然後執行方法體,方法結束時將棧針出棧,這個壓棧和出棧的過程會耗費資源,這個過程中傳遞形參也會耗費資源。

為什麼需要inline?

有些簡單的方法會被頻繁調用,什麼叫簡單的方法呢,舉個例子:

fun <T> check(lock: Lock, body: () -> T): T {
        lock.lock()
        try {
            return body()
        } finally {
            lock.unlock()
        }
    }

這個check方法的方法體中,不會將它的形參再傳遞給其他方法。我們調用一下 check 方法:

  check(l, {"我是lambda方法體"})//l是一個Lock對象

對於編譯器來說,調用 check 方法就要將參數l和 lambda 表達式 {"我是 lambda方法體"} 進行傳遞,還要將 check 方法進行壓棧出棧處理,這個過程就會耗費資源。

如果我們把 check 方法刪除,直接執行 check 方法的方法體:

        l.lock()
        try {
            return "我是lambda方法體"
        } finally {
            l.unlock()
        }

這樣做的效果和調用 check方法是一樣的,而且不需要壓棧出棧了,但是代碼是寫給人看的,這樣寫明顯產生了代碼壞味道,老司機會告訴你,這幾行代碼需要抽成一個方法,避免多處調用產生冗餘代碼。於是你就老老實實把這幾行代碼抽成了 check方法,那麼如上所述,一旦這個方法被頻繁調用,壓棧出棧將會帶來性能問題。針對這個問題,kotlin 引入了 inline 關鍵字。我們在 check 方法前加上 inline關鍵字:

inline fun <T> check(lock: Lock, body: () -> T): T {
        lock.lock()
        try {
            return body()
        } finally {
            lock.unlock()
        }
    }

然後我們再調用 check 方法,編譯器就會在編譯期幫我們進行優化:
將我們寫的代碼

  check(l, {"我是lambda方法體"})//l是一個Lock對象

換成

        l.lock()
        try {
            return "我是lambda方法體"
        } finally {
            l.unlock()
        }

也就是說 inline 關鍵字實際上增加了代碼量,但是提升了性能,而且增加的代碼量是在編譯期執行的,對程式可讀性不會造成影響。

其它

如果 check 方法中的參數需要傳遞給其他非 inline 方法:

inline fun <T> check(lock: Lock, body: () -> T): T {
            lock.lock()
            try {
                otherCheck(body)//會報錯
                return body()
            } finally {
                lock.unlock()
            }
    }

    fun <T> otherCheck(body: ()-> T){

    }

那麼調用 otherCheck 是會報錯的,因為 check 方法中的形參 body 現在已經 inline 了,不是一個函數對象了,也就不能作為一個參數傳遞了,除非在 body 參數前加上 noinline 關鍵字。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 用Google搜異常信息,肯定都訪問過 "Stack Overflow網站" 全球最大的程式員問答網站,名字來自於一個常見的報錯,就是棧溢出(stack overflow) 從函數調用開始,在電腦指令層面函數間的相互調用是怎麼實現的,以及什麼情況下會發生棧溢出 1 棧的意義 先看一個簡單的C程式 ...
  • 1、關閉防火牆 systemctl stop firewalld.service 停止firewall systemctl disable firewalld.service 禁止firewall開機啟動 2、切換用戶 3、編輯靜默安裝文件 4、修改配置文件 以下參數不要更改 [GENERAL] R ...
  • 相信大家都接觸過Mysql資料庫,而且也肯定都會寫sql。我不知道大家有沒有這樣的感受,反正我是有過這樣的想法。就是當我把一條sql語句寫完了,並且執行完得到想要的結果。這時我就在想為什麼我寫這樣的一條sql語句,就能給我查詢出我想要的結果,為什麼我寫了update就能更新一條語句?它們的執行過程是 ...
  • 1.首先安裝scala(找到合適版本的具體地址下載) 在/usr/local/目錄下 wget https://www.scala-lang.org/download/**** 2.安裝spark (由於我的Hadoop是2.7.6版本的,因此我所用的spark是在官網上的適用hadoop-2以上版 ...
  • Elasticsearch中的腳本(script)有什麼作用? 如何創建、搜索、使用腳本? 腳本的緩存又是什麼? 對於腳本的使用, 有哪些高效的實踐策略? 本篇博文對這些內容作個簡單的探討. ...
  • 轉載、節選於 https://dev.mysql.com/doc/refman/8.0/en/innodb-tablespace.html This section covers topics related to InnoDB tablespaces. 1.The System Tablespac ...
  • 簡單來說GPDB是一個分散式資料庫軟體,其可以管理和處理分佈在多個不同主機上的海量數據。對於GPDB來說,一個DB實例實際上是由多個獨立的PostgreSQL實例組成的,它們分佈在不同的物理主機上,協同工作,呈現給用戶的是一個DB的效果。Master是GPDB系統的訪問入口,其負責處理客戶端的連接及 ...
  • 前言 涉及到的源碼有 frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java vendor\mediatek\proprietary\packages\apps\SystemUI\src ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...