!= null VS ?let { } 性能 for Kotlin 中的不可变变量



据我了解,?.let{}相对于!= null的最大优势在于它保证了块内可变值不会更改。

但是,在不可变变量的情况下,是否存在性能差异?

例如,我有一个简单的方法

private fun test() {
val x: String? = ""
if (x != null) {
print("test")
}
x?.let {
print("test")
}
}

当我看到生成的 Kotlin 字节码时,似乎让它有更多的代码。

对于 x != 空情况:

LINENUMBER 8 L1
L2
LINENUMBER 9 L2
LDC "test"
ASTORE 2
L3
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ALOAD 2
INVOKEVIRTUAL java/io/PrintStream.print (Ljava/lang/Object;)V
L4
L5

对于 x?。设 { } 的情况是:

LINENUMBER 12 L5
ALOAD 1
ASTORE 2
L6
L7
ALOAD 2
ASTORE 3
L8
ICONST_0
ISTORE 4
L9
LINENUMBER 13 L9
LDC "test"
ASTORE 5
L10
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ALOAD 5
INVOKEVIRTUAL java/io/PrintStream.print (Ljava/lang/Object;)V
L11
L12
LINENUMBER 14 L12
L13
NOP
L14
LINENUMBER 12 L14
L15
NOP
L16

如果我反编译为 java,那么结果代码似乎类似于为 let 分配了一个变量(奇怪的是,一个 int 变量设置为 false)

对于 x != 空:

String var2 = "test";
System.out.print(var2);

对于 x?。让 { }

int var4 = false;
String var5 = "test";
System.out.print(var5);

最后,我的问题是:对于不可变变量,let 和!=之间的性能是否不同?

这两个语句实际上并不等价。在您的两个示例中,结果显然是相同的,但let是一个范围函数,因此比简单的流量控制更能提升一些。

从链接的文档:

Kotlin 标准库包含几个函数,其唯一目的是在对象的上下文中执行代码块。当您在提供了 lambda 表达式的对象上调用此类函数时,它会形成一个临时作用域。

例如,即使您没有在示例中使用it,仍然会创建带有 it 变量的上下文,并且会承担一些开销。

但是,正如其他人指出的那样,我认为在这种情况下,最好优化代码以提高可读性而不是速度。在 let 允许更多可读代码的情况下(IMO 通常是这种情况),这比使用 if 可能获得的微小性能增益更大。

最新更新