【问题标题】:Kotlin inline functions and Android methods countKotlin 内联函数和 Android 方法计数
【发布时间】:2018-01-01 16:45:53
【问题描述】:

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

InlineFunction.kt文件:

inline fun inlined(block: () -> Unit) {
    block()
}

还有MainActivity.kt文件:

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

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

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);
   }

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

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

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

我找到了Jake Wharton utility,但如果它工作正常,那么 Kotlin 库中的所有方法都会影响方法计数。这也意味着这个答案有问题https://stackoverflow.com/a/39635849/4727432

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

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

【问题讨论】:

    标签: java android compilation kotlin dex


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 太棒了!现在对我来说很清楚了。它还极大地解释了为什么 lint 会在没有 lambda 的情况下警告 inline
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-01
    • 1970-01-01
    • 2018-09-07
    • 2017-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多