K2是Kotlin编译器的新前端。该编译器已经可以预览,可以将来将来发布Kotlin 2.0。
上周,官方的Android开发人员博客发布了另一个article,鼓励开始测试新编译器。在本文中,我们将分享在NowInandroid项目中使用K2的结果。
项目
- nowinandroid
- 提交:0a20cb7(2023年8月2日)
- gradle 8.2
- AGP 8.1.0
- kgp 1.9.0
方案
我们定义了两个主要情况:
- 清洁构建
- 增量构建
在两种情况下使用的两个变体都是Main(分支)和K2,它基于gradle中的主要分支。
kotlin.experimental.tryK2=true
清洁构建
对于每个变体,我们使用Gradle Enterprise API在GitHub跑步者中执行了100个并行构建,以检索数据。
两个变体的构建执行是:
主要 | k2 | |
---|---|---|
平均值 | 15m 23s | 15m 22s |
中值 | 15m 28S | 15m 21s |
我们没有注意到有很大的差异。我们知道,这可能是由构建执行中涉及的不同任务引起的。最后,K2仅影响构建中的一部分任务。我们通过按类型(MS)汇总了Kotlin相关任务的持续时间:
,继续进行了更多详细分析。类型 | 主要 | k2 | |
---|---|---|---|
kotlincompile | 平均值 | 2818 | 2800 |
kotlincompile | 中值 | 1682 | 1812 |
KaptgenerateStubStask | 平均值 | 853 | 1067 |
KaptgenerateStubStask | 中值 | 515 | 669 |
kaptwithoutkotlinctask | 平均值 | 1049 | 1106 |
kaptwithoutkotlinctask | 中值 | 1682 | 1812 |
仍然,聚集并未显示多汁的数据。
重要的是要强调,当使用K2构建项目时,KSP和KAPT任务当前恢复使用旧编译器:
:功能:foryou:kaptgeneratestubsdemoreleasekotlin
W:Kapt当前不支持2.0+语言版本。
降至1.9。
因此,我们仅专注于Kotlin编译器任务结果。
我们需要在分析中获得更多详细信息,因此我们选择了DemoDebug
构建变体,并按任务路径分析了中位数:
在这一点上,我们开始看到特定任务的差异,在某些情况下是肯定的,而在其他情况下为负面。
取得这些结果,我们表示相对于主要分支的持续时间差的%:
这给了我们更多的提示。为了丢弃可能的离群值,我们验证了测量中最坏,最佳的结果:
- UI检验:Hilt-Manifest
- 核心:Dataster li>
看起来不错。
为了更好地理解差异的起源,我们使用了Kotlin Build Reports。此功能使我们能够获得有关Kotlin编译器指标的更多详细信息。要启用它,请在gradle中添加属性。
kotlin.build.report.output=build_scan
一旦启用Kotlin构建报告,就可以在编译器信息的构建扫描中创建自定义值:
我们汇总了Kotlin构建报告的数据,并为正在调查的任务提供了中位数:
: :ui-test-hilt-manifest
指标给出的结果明显较差:
- 编译器代码分析
- 编译器代码生成
- Gradle Worker中的运行汇编
- 资源汇编
此模块仅在主要app上的debugImplementation
中使用,用于调用挂钩匕首图配置的组合的测试。此外,我怀疑KAPT/HILT配置也可能影响。
core:datastore:compileDemoDebugKotlin
减少了:
- 代码生成线每秒
- 编译器代码分析
- Gradle Worker中的运行汇编
- 资源汇编 但是,我们观察到: 的持续时间增加
- 编译器代码生成
此模块在我们的代码库中代表更好的一个真实的Android模块,我们可以确认使用K2的任务持续时间减少了25%。伟大的!
为了完成本节,我发现使用Kotlin Build Reports分享项目中其他模块的指标很有趣:
增量构建
使用Gradle Profiler,我们定义了一个方案,在该场景中我们将增量更改应用于类core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/NewsRepository.kt
。
每个变体都为任务testDemoDebugUnitTest
执行50个构建。
分析整体构建时间的结果为:
主要 | k2 | |
---|---|---|
平均值 | 1M 4S | 1m 20s |
中值 | 1M 1S | 1M 16S |
我们略微增加了整体构建时间。我们重复了由Kotlin编译器任务分组的上一个方案的相同过程:
类型 | 主要 | k2 | |
---|---|---|---|
kotlincompile | 平均值 | 1267 | 1891 |
kotlincompile | 中值 | 1033 | 1290 |
平均值和中位数之间的差距使我们认为在K2变体期间发生了性能问题。我们检索了Kotlin process的GC时间,并确认了假设:
指出使用K2引起的内存泄漏之前,可以公平地提到这些实验是在有限资源的免费GitHub跑步者中执行的。可用的内存为7 GB,使用3 GB用于每个过程(Kotlin/gradle)。
我们将迭代次数减少到K2变体中的10个,并继续调查。减少迭代后,结果为:
主要 | k2 | |
---|---|---|
平均值 | 1267 | 1284 |
中值 | 1033 | 1076 |
这次,我们有更接近的结果。然后,我们可视化由任务路径分组的数据:
K2在增量构建的所有任务中都获得了更好的时间
使用Kotlin Build Report
:core:data
,应用增量变化的模块显示:
- 编译器代码分析
- Gradle Worker中的运行汇编
- 资源汇编 但是,我们观察到: 的持续时间增加
- 编译器代码生成
:feature:interest
显示总构建时间增加了10%。在分析模块后,我们没有找到与其他特征模块相比的该特定模块行为的正确解释。
最终单词
K2在这里,看起来很有希望。
在实验下的项目并不代表生产项目。其他项目的结果可能有所不同。
KAPT/KSP落回旧的编译器可能会影响最终结果,一旦它们兼容,我们可能会期望更好的结果。
到目前为止,我们在本文中看到了使用K2可显着改善Kotlin编译器的构建时间。
快乐建筑!