Search code examples
stringkotlinstring-concatenationstring-interpolation

Kotlin - String interpolation $ vs concatenate using plus-equals +=


The problem is quite simple: What is the difference between these 2 versions (both have initialized var name: String and val someInt: Int)?

name += " $someInt"

name = "$name $someInt"

I also read that the String interpolation $ uses a StringBuilder, so the second code should be preferred to the first one (which uses concatenation) ?


Solution

  • The best way to find the difference is to look at the generated bytecode (I will use Kotlin 1.4.10).

    Bytecode generated for name += " $someInt":

    ALOAD 0
    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    SWAP
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    BIPUSH 32
    INVOKEVIRTUAL java/lang/StringBuilder.append (C)Ljava/lang/StringBuilder;
    ILOAD 1
    INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
    ASTORE 0
    

    Bytecode generated for name = "$name $someInt":

    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    ALOAD 0
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    BIPUSH 32
    INVOKEVIRTUAL java/lang/StringBuilder.append (C)Ljava/lang/StringBuilder;
    ILOAD 1
    INVOKEVIRTUAL java/lang/StringBuilder.append (I)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
    ASTORE 0
    

    Results are pretty much the same, but in the first case there is an extra SWAP operation, cause argument for first append operation was loaded onto stack too early (before StringBuilder was created, and now they need to be swapped).

    TL;DR

    Turns out that:

    1. StringBuilder is created in both cases
    2. There are 3 appends (name, whitespace & someInt) in both cases
    3. Second one is slightly more effective.