kotlin - != null VS ?.let { } kotlin 中不可变变量的性能
问题描述
据我了解,?.let{}
over的最大优势!= 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 和for 不可变变量之间的性能是否不同?
解决方案
The two statements are not really equivalent. The outcome is obviously the same in your two examples, but let
is a scope function and thus is doing a bit more lifting than simple flow control.
From the linked documentation:
The Kotlin standard library contains several functions whose sole purpose is to execute a block of code within the context of an object. When you call such a function on an object with a lambda expression provided, it forms a temporary scope.
For example even if you're not using the it
in your example, this context with the it-variable is still created and that bears some overhead with it.
However, as others have pointed out I think this is a case where it's better to optimize the code for readability over speed in this case. In cases where a let allows for more readable code (which IMO is usually the case), that's a bigger win than the miniscule performance gain you may get from using an if instead.
推荐阅读
- reactjs - 在 TypeScript 中获取泛型函数的参数
- bash - Cron 未将输出写入日志文件
- azure - Azure ARM 模板 - 参数与属性上的静态值相结合
- r - 在 Windows 10 上 clickElement() 后 RSelenium 崩溃
- java - 递归查找字符串中字符的出现次数(java)
- functional-programming - Scheme中最长的数字子集
- c# - WPF“重叠”滚动查看器
- visual-studio-code - 等到符号提供程序可用
- spring-boot - 如何使用 gradle 下载所有 Spring Boot 依赖项
- google-apps-script - 使用谷歌表格中的命名范围作为自定义公式中的变量