据我了解,?.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 可能获得的微小性能增益更大。