Kotlin 内联函数和 Android 方法计数

hlu*_*kyi 5 java android compilation dex kotlin

我想了解内联函数如何影响classes.dex方法的数量和数量。根据我的理解,内联函数应该对方法计数的开销为零。然而,APK 分析器给了我相反的结果。我写了一个小测试来检查这个。

InlineFunction.kt 文件:

inline fun inlined(block: () -> Unit) {
    block()
}
Run Code Online (Sandbox Code Playgroud)

MainActivity.kt文件:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        inlined {
            println("Inlined")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

从生成的代码的角度来看,它看起来很清楚:

public final class MainActivity extends AppCompatActivity {
    private HashMap _$_findViewCache;

    protected void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       String var2 = "Inlined";
       System.out.println(var2);
   }
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,没有调用其他方法。但是如果我用分析器打开 apk,我可以看到这个方法影响了定义和引用的方法计数。

在此处输入图片说明

另一方面,Kotlin stdlib 只影响引用的方法计数,而不影响定义的方法。

在此处输入图片说明

那么我错过了什么?我找不到关于 Android 中内联方法的任何好的来源以及它如何影响性能以及我找不到任何文档如何计算 dex 方法计数。

我找到了Jake Wharton 实用程序,但如果它工作正常,那么 Kotlin 库中的所有方法都会影响方法计数。这也意味着这个答案有问题/sf/answers/2774509461/

...标准库非常小,它的许多函数都是内联的,这意味着它们在编译后不存在,只是成为内联代码。Proguard 也可以处理很多事情......

那么内联函数如何影响方法计数呢?欢迎任何解释 dex 方法计数过程的文章或帖子。

vod*_*dan 5

即使被标记inline为从 java 调用,Kotlin 也会生成真正的方法,因此它们仍然反映在 dex 计数中。

内联有用的地方是无开销的 lambda。通常,每个 lambda 在每个调用位置都至少用一个方法(有时甚至是一个类)表示。但内联 lambda 会跳过此开销,因此不会影响 dex 计数。

标准库非常小,并且许多函数都是内联的

标准库@inlineOnly对某些方法使用特殊技巧(注释)来跳过生成内联函数的方法(如上所述)。但这个注解是包内部的kotlin,不能在普通代码中使用。