Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift string via string literal vs initializer

In other languages such as Java, under the hood there is actually a difference between string obtained via string literal vs initializer. In Swift, are they equivalent under the hood?

e.g.

var string:String = ""
var string:String = String()

Refer to this SO post for info on differences between literal and object in Java.

like image 715
Boon Avatar asked Jul 03 '15 01:07

Boon


People also ask

Which is better string literal or string object?

In general, we should use the String literal notation when possible. It is easier to read and it gives the compiler a chance to optimize our code.

Is there a difference between a string and a string literal?

The main difference between String Literal and String Object is that String Literal is a String created using double quotes while String Object is a String created using the new() operator. String is a set of characters. Generally, it is necessary to perform String operations in most applications.

What is a string literal in Swift?

String literal is the sequence of characters enclosed in double quote. This can also be used for initializing the string. When a variable is initialized with string literal, Swift compiler infer it as String type.

How do you initialize a string in Swift?

Initializing an Empty String To create an empty String value as the starting point for building a longer string, either assign an empty string literal to a variable, or initialize a new String instance with initializer syntax: var emptyString = "" // empty string literal.


1 Answers

The declarations are equivalent according to the Apple docs:

Initializing an Empty String

To create an empty String value as the starting point for building a longer string, either assign an empty string literal to a variable, or initialize a new String instance with initializer syntax:

var emptyString = ""               // empty string literal
var anotherEmptyString = String()  // initializer syntax
// these two strings are both empty, and are equivalent to each other

Reference: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html

If we look at the assembly, we will see that the two constructors use identical instructions.

string.swift:

let str = String()
let str2 = ""

Compiled assembly (swiftc -emit-assembly string.swift):

    .section    __TEXT,__text,regular,pure_instructions
    .macosx_version_min 14, 3
    .globl  _main
    .align  4, 0x90
_main:
    .cfi_startproc
    pushq   %rbp
Ltmp0:
    .cfi_def_cfa_offset 16
Ltmp1:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp2:
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movq    _globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_token4@GOTPCREL(%rip), %rax
    movq    _globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_func4@GOTPCREL(%rip), %rcx
    xorl    %edx, %edx
    movl    %edi, -4(%rbp)
    movq    %rax, %rdi
    movq    %rsi, -16(%rbp)
    movq    %rcx, %rsi
    callq   _swift_once
    movq    _globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_token5@GOTPCREL(%rip), %rdi
    movq    _globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_func5@GOTPCREL(%rip), %rax
    xorl    %r8d, %r8d
    movl    %r8d, %edx
    movq    __TZvOSs7Process5_argcVSs5Int32@GOTPCREL(%rip), %rcx
    movl    -4(%rbp), %r8d
    movl    %r8d, (%rcx)
    movq    %rax, %rsi
    callq   _swift_once
    movq    __TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__@GOTPCREL(%rip), %rax
    movq    -16(%rbp), %rcx
    movq    %rcx, (%rax)
    callq   __TFSSCfMSSFT_SS
    leaq    L___unnamed_1(%rip), %rdi
    xorl    %r8d, %r8d
    movl    %r8d, %esi
    movl    $1, %r8d
    movq    %rax, __Tv6string3strSS(%rip)
    movq    %rdx, __Tv6string3strSS+8(%rip)
    movq    %rcx, __Tv6string3strSS+16(%rip)
    movl    %r8d, %edx
    callq   __TFSSCfMSSFT21_builtinStringLiteralBp8byteSizeBw7isASCIIBi1__SS
    xorl    %r8d, %r8d
    movq    %rax, __Tv6string4str2SS(%rip)
    movq    %rdx, __Tv6string4str2SS+8(%rip)
    movq    %rcx, __Tv6string4str2SS+16(%rip)
    movl    %r8d, %eax
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .globl  __Tv6string3strSS
.zerofill __DATA,__common,__Tv6string3strSS,24,3
    .globl  __Tv6string4str2SS
.zerofill __DATA,__common,__Tv6string4str2SS,24,3
    .section    __TEXT,__cstring,cstring_literals
L___unnamed_1:
    .space  1

    .no_dead_strip  __Tv6string3strSS
    .no_dead_strip  __Tv6string4str2SS
    .linker_option "-lswiftCore"
    .section    __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
    .long   0
    .long   512


.subsections_via_symbols

Notice that the declarations for str and str2 have identical instructions:

xorl    %r8d, %r8d
movl    %r8d, %esi
movl    $1, %r8d
movq    %rax, __Tv6string3strSS(%rip)
movq    %rdx, __Tv6string3strSS+8(%rip)
movq    %rcx, __Tv6string3strSS+16(%rip)
movl    %r8d, %edx

# ...

xorl    %r8d, %r8d
movq    %rax, __Tv6string4str2SS(%rip)
movq    %rdx, __Tv6string4str2SS+8(%rip)
movq    %rcx, __Tv6string4str2SS+16(%rip)
movl    %r8d, %eax

You can learn more about String literals by reviewing the Apple's documentation.

like image 149
JAL Avatar answered Oct 13 '22 15:10

JAL