Fastest, leanest way to append characters to form a string in Swift

(This answer was written based on documentation and source code valid for Swift 2 and 3: possibly needs updates and amendments once Swift 4 arrives)

Since Swift is now open-source, we can actually have a look at the source code for Swift:s native String

  • swift/stdlib/public/core/String.swift

From the source above, we have following comment

/// Growth and Capacity
/// ===================
///
/// When a string's contiguous storage fills up, new storage must be
/// allocated and characters must be moved to the new storage.
/// `String` uses an exponential growth strategy that makes `append` a
/// constant time operation *when amortized over many invocations*.

Given the above, you shouldn’t need to worry about the performance of appending characters in Swift (be it via append(_: Character), append(_: UniodeScalar) or appendContentsOf(_: String)), as reallocation of the contiguous storage for a certain String instance should not be very frequent w.r.t. number of single characters needed to be appended for this re-allocation to occur.

Also note that NSMutableString is not “purely native” Swift, but belong to the family of bridged Obj-C classes (accessible via Foundation).


A note to your comment

“I thought that String was immutable, but I noticed its append method returns Void.”

String is just a (value) type, that may be used by mutable as well as immutable properties

var foo = "foo" // mutable 
let bar = "bar" // immutable
    /* (both the above inferred to be of type 'String') */

The mutating void-return instance methods append(_: Character) and append(_: UniodeScalar) are accessible to mutable as well as immutable String instances, but naturally using them with the latter will yield a compile time error

let chars : [Character]  = ["b","a","r"]
foo.append(chars[0]) // "foob"
bar.append(chars[0]) // error: cannot use mutating member on immutable value ...

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)