问题
When specifically dealing with non-optional String
values, what could be the difference between String interpolation and String concatenation?
struct MyModel {
let value1: String
let value2: String
var displayNameByConcatenation: String {
return value1 + "-" + value2
}
var displayNameByInterpolation: String {
return "\(value1)-\(value2)"
}
}
- Is there going to be any case where
displayNameByConcatenation
anddisplayNameByInterpolation
are different? Like on long unicode strings? - Is it possible to somehow override the behavior of operator
+
or the behavior of interpolation to make them different in above example? - Is one faster/slower than the other?
Note that from this question we learn that string interpolation will use the description
of a CustomStringConvertible. But does String
concatenation (operator +
) also calls the description
?
回答1:
From a speed point of view, to differentiate concatenation (value1 + "-" + value2
) and interpolation ("\(value1)-\(value2)"
), results may depend on the number of operations done to obtain the final string.
My results on an iPhone 8 show that:
- if there is roughly < 30 substrings to attach together, then concatenation is faster
- if there is roughly > 30 substrings to attach together, then interpolation is faster
Thank you Sirens for figuring out that one wasn't always faster than the other!
Try it yourself (and don't forget to adapt the tested character set and iterations for your needs):
import UIKit
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
DispatchQueue.global(qos: .default).async {
ViewController.buildDataAndTest()
}
}
private static func buildDataAndTest(times: Int = 1_000) {
let characterSet = CharacterSet.alphanumerics
characterSet.cacheAllCharacters()
let data: [(String, String)] = (0 ..< times).map { _ in
(characterSet.randomString(length: 50), characterSet.randomString(length: 20))
}
_ = testCIA(data)
_ = testInterpol(data)
print("concatenation: " + String(resultConcatenation))
print("interpolation: \(resultInterpolation)")
}
/// concatenation in array
static var resultConcatenation: CFTimeInterval = 0
private static func testCIA(_ array: [(String, String)]) -> String {
var foo = ""
let start = CACurrentMediaTime()
for (a, b) in array {
foo = foo + " " + a + "+" + b
}
resultConcatenation = CACurrentMediaTime() - start
return foo
}
/// interpolation
static var resultInterpolation: CFTimeInterval = 0
private static func testInterpol(_ array: [(String, String)]) -> String {
var foo = ""
let start = CACurrentMediaTime()
for (a, b) in array {
foo = "\(foo) \(a)+\(b)"
}
resultInterpolation = CACurrentMediaTime() - start
return foo
}
}
extension CharacterSet {
static var cachedCharacters: [Character] = []
public func cacheAllCharacters() {
CharacterSet.cachedCharacters = characters()
}
/// extracting characters
/// https://stackoverflow.com/a/52133647/1033581
public func characters() -> [Character] {
return codePoints().compactMap { UnicodeScalar($0) }.map { Character($0) }
}
public func codePoints() -> [Int] {
var result: [Int] = []
var plane = 0
for (i, w) in bitmapRepresentation.enumerated() {
let k = i % 8193
if k == 8192 {
plane = Int(w) << 13
continue
}
let base = (plane + k) << 3
for j in 0 ..< 8 where w & 1 << j != 0 {
result.append(base + j)
}
}
return result
}
// http://stackoverflow.com/a/42895178/1033581
public func randomString(length: Int) -> String {
let charArray = CharacterSet.cachedCharacters
let charArrayCount = UInt32(charArray.count)
var randomString = ""
for _ in 0 ..< length {
randomString += String(charArray[Int(arc4random_uniform(charArrayCount))])
}
return randomString
}
}
回答2:
"Concatenation allows you to combine to strings together and it only works on two strings."
An update. Not sure what earlier versions of Swift allowed, but currently you can concatenate more than 2 Strings together in the same statement:
let str = "Hi, my name is "
var concat = str + "2" + "3" + "4" + "5" + " works" //displays "Hi, my name is 2345 works"
Because both operands of + need to be Strings, you have to do a little extra work if you want to add a number to a String:
var concat2 = str + String(2) //displays "Hi, my name is 2"
Reason why interpolation rather than concatenation, here's a quote from Apple's intro for interpolation: "String interpolation is a way to construct a new String value from a mix of constants, variables, literals, and expressions" In other words, you can use interpolation with numbers, booleans, etc. without first turning them into Strings, which you would have to do if you used concatenation.
回答3:
string interpolation:
- less typing
- Internally calls to string
- faster during the run time
one disadvantage:
- delimit your string
Both interpolation and concatenation has its own strength and weakness
Need to use concatenation with predefined string to get better performance
来源:https://stackoverflow.com/questions/42849545/difference-between-string-interpolation-and-string-concatenation