【发布时间】:2019-09-03 00:18:37
【问题描述】:
据我了解,?.let{} 相对于!= null 的最大优势在于它保证了可变值不会在块内更改。
但是,在不可变变量的情况下是否存在性能差异?
比如我有一个简单的方法
private fun test() {
val x: String? = ""
if (x != null) {
print("test")
}
x?.let {
print("test")
}
}
当我看到生成的 Kotlin 字节码时,似乎让它有更多的代码。
对于 x != null 情况:
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?.let { } 情况是:
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 != null:
String var2 = "test";
System.out.print(var2);
对于 x?.let { }
int var4 = false;
String var5 = "test";
System.out.print(var5);
最后,我的问题是:对于不可变变量,let 和!= 之间的性能是否存在差异?
【问题讨论】:
-
这是一个微优化的例子——差异是如此微小,你甚至很难测量它。只需使用上下文中更具可读性的内容即可。
-
@Pawel:同意。巨大的性能优势来自于避免不必要的:同步/线程、算法复杂性、网络/文件/DB I/O、临时对象和(在较小程度上)主内存访问。这里的优化不会减少任何这些,因此在实践中它永远不会产生任何实际差异。事实上,无论如何,JVM 可能会对其进行优化。
-
我只是在反编译版本中看到太多行但我看不懂它是什么,这就是我想知道的原因!
标签: kotlin null-check