R8 如何优化我们的代码(2) -- 空值数据流分析

剪枝

kotlin 复制代码
package org.example

fun <T : Any> coalesce(a: T?, b: T?): T? = a ?: b


fun main() {
    println(coalesce("one", "two"))
    println(coalesce(null, "two"))
}

这段代码比较简单, 对 R8 稍微有点了解的人可能会马上反应过来,这个函数因为过于简单,所以大概率是会被 R8 内联的, 内联以后的代码等效于

go 复制代码
println("one" ?: "two")
println(null ?: "two")

但实际上我们 r8 处理过之后的代码是这样:

你会发现做的比较激进,不只是做了内联,甚至还帮我们做了 Pruning 说人话就是剪枝

这个概念大家自行搜索关键词学习即可,这里就不展开了。我粗浅的理解就是 剪枝的过程就是帮我们排除那些不可能达到的分支代码,并将其移除

空值检查

kotlin 自带空值检查 这个大家肯定都比较熟悉了

kotlin 复制代码
fun String.double(): String = this + this

fun coalesce(a: String?, b: String?): String? = a ?: b

fun main(args: Array<String>) {
    println(coalesce(null, "two")?.double())
}

未使用 r8时,有多条 kotlin 的空值检查语句

使用 r8 之后

多余的空值检查被去除

java中的空值检查

虽然 java 不像 kotlin 中自带空值检查,但是r8 一样对其有着优化

可以看下这个 first 函数

java 复制代码
final class Nulls {
    public static void main(String[] args) {
        System.out.println(first(args));
        if (args == null) {
            System.out.println("null!");
        }
    }

    public static String first(String[] values) {
        if (values == null) throw new NullPointerException("values == null");
        return values[0];
    }
}

需要额外改一下 rules

arduino 复制代码
-keep class Nulls {
   public static java.lang.String first(java.lang.String[]);
}

可以看下未使用 r8 时的指令

使用 r8 之后的指令

显然使用r8 指令之后的 first 方法显的更为高效,因为 null 的条件语句被后置了 从字节码指令的角度来看 显然是 r8 的指令更为效率了

相关推荐
恋猫de小郭7 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab8 小时前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe13 小时前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农20 小时前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少20 小时前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker21 小时前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋21 小时前
Android 协程时代,Handler 应该退休了吗?
android
火柴就是我1 天前
让我们实现一个更好看的内部阴影按钮
android·flutter
砖厂小工2 天前
用 GLM + OpenClaw 打造你的 AI PR Review Agent — 让龙虾帮你审代码
android·github
张拭心2 天前
春节后,有些公司明确要求 AI 经验了
android·前端·人工智能