Dies ist fast die gleiche wie die akzeptierte Antwort, aber mit einigen zusätzlichen Dialogen (ich hatte mit Rob Napier, seinen anderen Antworten und Matt, Oliver, David von Slack) und Links.
Siehe die Kommentare in dieser Diskussion. Der Kern davon ist:
+
ist stark überlastet (Apple scheint dies in einigen Fällen behoben zu haben)
Der +
Operator ist stark überlastet, da er derzeit 27 verschiedene Funktionen hat. Wenn Sie also 4 Zeichenfolgen verketten, dh 3 +
Operatoren haben, muss der Compiler jedes Mal zwischen 27 Operatoren prüfen , das sind also 27 ^ 3-mal. Aber das ist es nicht.
Es wird auch überprüft , ob das lhs
und rhs
das der +
Funktionen beide gültig sind, wenn sie append
aufgerufen werden, um das aufgerufene zu kernen . Dort können Sie sehen, dass eine Reihe von etwas intensiven Überprüfungen auftreten können. Wenn die Zeichenfolge nicht zusammenhängend gespeichert ist, scheint dies der Fall zu sein, wenn die Zeichenfolge, mit der Sie sich befassen, tatsächlich mit NSString verbunden ist. Swift muss dann alle Byte-Array-Puffer zu einem einzigen zusammenhängenden Puffer zusammensetzen, was das Erstellen neuer Puffer auf dem Weg erfordert. und dann erhalten Sie schließlich einen Puffer, der die Zeichenfolge enthält, die Sie miteinander verketten möchten.
Auf den Punkt gebracht ist es 3 Cluster von Compiler überprüft , die Sie nach unten , dh verlangsamt jeder Unterausdruck hat angesichts der alles überdacht werden es könnte zurückkehren . Als Ergebnis Strings mit Interpolation verketten dh unter Verwendung " My fullName is \(firstName) \(LastName)"
ist viel besser als "My firstName is" + firstName + LastName
da Interpolation nicht hat jede Überlastung hat
Swift 3 hat einige Verbesserungen vorgenommen. Weitere Informationen finden Sie unter Zusammenführen mehrerer Arrays, ohne den Compiler zu verlangsamen. . Trotzdem ist der +
Operator immer noch überlastet und es ist besser, die String-Interpolation für längere Strings zu verwenden
Verwendung von Optionen (laufendes Problem - Lösung verfügbar)
In diesem sehr einfachen Projekt:
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"
}
Die Kompilierungszeit für die Funktionen ist wie folgt:
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()
Beachten Sie, wie verrückt die Kompilierungsdauer concatenatedOptionals
ist.
Dies kann gelöst werden durch:
let emptyString: String = ""
func concatenatedOptionals() -> String {
return (p2.firstName ?? emptyString) + emptyString + (p2.lastName ?? emptyString) + (p2.status ?? emptyString)
}
welches kompiliert in 88ms
Die Ursache des Problems ist , dass der Compiler identifiziert nicht die ""
als ein String
. Es ist eigentlichExpressibleByStringLiteral
Der Compiler sieht alle Typen, die diesem Protokoll entsprechen , ??
und muss sie durchlaufen , bis er einen Typ findet, der standardmäßig verwendet werden kann String
. Durch die Verwendung von emptyString
Hardcodierung String
muss der Compiler nicht mehr alle konformen Typen von durchlaufenExpressibleByStringLiteral
Informationen zum Protokollieren der Kompilierungszeiten finden Sie hier oder hier
Andere ähnliche Antworten von Rob Napier auf SO:
Warum dauert das Erstellen von Strings so lange?
Wie kann man mehrere Arrays zusammenführen, ohne den Compiler zu verlangsamen?
Swift Array enthält Funktionen, die die Build-Zeiten verlängern
var statement = "create table if not exists \(self.tableName()) (\(columns))"
?