Це майже так само, як прийнята відповідь, але з деяким додатковим діалогом (я мав з Роб Неп'єром, його іншими відповідями та Меттом, Олівером, Девідом з Слака) та посиланнями.
Дивіться коментарі в цій дискусії. Суть її полягає в:
+ сильно перевантажений (Apple, здається, виправила це в деяких випадках)
+Оператор сильно перевантажений, як зараз вона має 27 різних функцій , так що якщо ви конкатенація 4 рядки , тобто у вас є 3 +операторів, компілятор повинен перевірити між 27 операторами , кожен раз, так що 27 ^ 3 рази. Але це не все.
Існує також перевірка , щоб побачити , якщо lhsі rhsз +функцій є дійсними , якщо вони викликаються через до сердечника appendназивається. Там ви можете побачити ряд інтенсивних перевірок, які можуть відбутися. Якщо рядок зберігається безперервно, це, мабуть, випадок, якщо рядок, з якою ви маєте справу, фактично з'єднаний з NSString. Потім Swift повинен повторно зібрати всі байтові буфери масиву в єдиний суміжний буфер, що вимагає створення нових буферів по дорозі. а потім ви отримаєте один буфер, який містить рядок, який ви намагаєтеся об'єднати разом.
Коротше кажучи, є 3 кластери перевірки компілятора, які сповільнюватимуть вас, тобто кожен підвираз повинен переглядатись у світлі всього, що може повернутися . В результаті об'єднання рядків з інтерполяцією, тобто використання " My fullName is \(firstName) \(LastName)"набагато краще, ніж "My firstName is" + firstName + LastNameоскільки інтерполяція не має перевантаження
Swift 3 внесла деякі вдосконалення. Для отримання додаткової інформації читайте Як об'єднати кілька масивів без уповільнення компілятора? . Тим не менш, +оператор все ще перевантажений, і краще використовувати інтерполяцію рядків для довших рядків
Використання додаткових варіантів (поточна проблема - рішення доступне)
У цьому дуже простому проекті:
import UIKit
class ViewController: UIViewController {
let p = Person()
let p2 = Person2()
func concatenatedOptionals() -> String {
return (p2.firstName ?? "") + "" + (p2.lastName ?? "") + (p2.status ?? "")
}
func interpolationOptionals() -> String {
return "\(p2.firstName ?? "") \(p2.lastName ?? "")\(p2.status ?? "")"
}
func concatenatedNonOptionals() -> String {
return (p.firstName) + "" + (p.lastName) + (p.status)
}
func interpolatedNonOptionals() -> String {
return "\(p.firstName) \(p.lastName)\(p.status)"
}
}
struct Person {
var firstName = "Swift"
var lastName = "Honey"
var status = "Married"
}
struct Person2 {
var firstName: String? = "Swift"
var lastName: String? = "Honey"
var status: String? = "Married"
}
Час компіляції для функцій є таким:
21664.28ms /Users/Honey/Documents/Learning/Foundational/CompileTime/CompileTime/ViewController.swift:16:10 instance method concatenatedOptionals()
2.31ms /Users/Honey/Documents/Learning/Foundational/CompileTime/CompileTime/ViewController.swift:20:10 instance method interpolationOptionals()
0.96ms /Users/Honey/Documents/Learning/Foundational/CompileTime/CompileTime/ViewController.swift:24:10 instance method concatenatedNonOptionals()
0.82ms /Users/Honey/Documents/Learning/Foundational/CompileTime/CompileTime/ViewController.swift:28:10 instance method interpolatedNonOptionals()
Зауважте, наскільки шалено висока тривалість компіляції concatenatedOptionals.
Це можна вирішити, виконавши:
let emptyString: String = ""
func concatenatedOptionals() -> String {
return (p2.firstName ?? emptyString) + emptyString + (p2.lastName ?? emptyString) + (p2.status ?? emptyString)
}
який компілює в 88ms
Першопричиною проблеми є те, що компілятор не ідентифікує ""як String. Це насправдіExpressibleByStringLiteral
Компілятор побачить ??і доведеться переглядати всі типи, які відповідають цьому протоколу , доки він не знайде тип, який може бути типовим String. Використовуючи те, emptyStringщо важко кодується String, компілятору більше не потрібно пробирати всі відповідні типиExpressibleByStringLiteral
Щоб дізнатися, як записувати час складання, дивіться тут або тут
Інші подібні відповіді Роб Нап'єр на SO:
Чому додавання рядків займає стільки часу для створення?
Як об'єднати кілька масивів, не уповільнюючи компілятор?
Swift Array містить функцію, що збільшує час збирання
var statement = "create table if not exists \(self.tableName()) (\(columns))":?