首页 > 解决方案 > != 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 不可变变量之间的性能是否不同?

标签: kotlinnull-check

解决方案


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.


推荐阅读