Điều này gần giống như câu trả lời được chấp nhận nhưng với một số đoạn hội thoại được thêm vào (tôi đã có với Rob Napier, các câu trả lời khác của anh ấy và Matt, Oliver, David từ Slack) và các liên kết.
Xem các ý kiến trong cuộc thảo luận này . Ý chính của nó là:
+
bị quá tải (Apple dường như đã sửa lỗi này trong một số trường hợp)
Các +
nhà điều hành được nhiều quá tải, tính đến bây giờ nó có 27 chức năng khác nhau vì vậy nếu bạn đang concatenating 4 chuỗi tức là bạn có 3 +
nhà khai thác trình biên dịch phải kiểm tra giữa 27 nhà khai thác mỗi lần, vì vậy đó là 27 ^ 3 lần. Nhưng đó không phải là nó.
Ngoài ra còn có một kiểm tra để xem nếu lhs
và rhs
của các +
chức năng đều hợp lệ nếu chúng được gọi thông qua lõi để append
gọi. Ở đó bạn có thể thấy có một số kiểm tra chuyên sâu có thể xảy ra. Nếu chuỗi được lưu trữ không liền kề, điều này dường như là trường hợp nếu chuỗi bạn đang xử lý thực sự được kết nối với NSString. Swift sau đó phải lắp ráp lại tất cả các bộ đệm mảng byte thành một bộ đệm liền kề duy nhất và yêu cầu tạo bộ đệm mới trên đường đi. và cuối cùng bạn nhận được một bộ đệm chứa chuỗi bạn đang cố gắng nối với nhau.
Tóm lại, có 3 cụm kiểm tra trình biên dịch sẽ làm bạn chậm lại, tức là mỗi biểu thức phụ phải được xem xét lại trong mọi thứ mà nó có thể trả về . Kết quả là các chuỗi kết hợp với phép nội suy tức là sử dụng " My fullName is \(firstName) \(LastName)"
sẽ tốt hơn nhiều so với "My firstName is" + firstName + LastName
phép nội suy không có bất kỳ sự quá tải nào
Swift 3 đã thực hiện một số cải tiến. Để biết thêm thông tin đọc Làm thế nào để hợp nhất nhiều Mảng mà không làm chậm trình biên dịch? . Tuy nhiên, +
toán tử vẫn bị quá tải và tốt hơn là sử dụng phép nội suy chuỗi cho chuỗi dài hơn
Sử dụng các tùy chọn (vấn đề đang diễn ra - giải pháp có sẵn)
Trong dự án rất đơn giản này:
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"
}
Thời gian biên dịch cho các hàm là như sau:
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()
Lưu ý rằng thời gian biên dịch điên rồ cao đến mức nào concatenatedOptionals
.
Điều này có thể được giải quyết bằng cách làm:
let emptyString: String = ""
func concatenatedOptionals() -> String {
return (p2.firstName ?? emptyString) + emptyString + (p2.lastName ?? emptyString) + (p2.status ?? emptyString)
}
mà biên dịch trong 88ms
Nguyên nhân cốt lõi của vấn đề là trình biên dịch không xác định ""
là a String
. Nó thực sựExpressibleByStringLiteral
Trình biên dịch sẽ thấy ??
và sẽ phải lặp qua tất cả các loại đã tuân thủ giao thức này , cho đến khi nó tìm thấy một loại có thể là mặc định String
. Bằng cách sử dụng emptyString
mã hóa cứng String
, trình biên dịch không còn cần phải lặp qua tất cả các loại tuân thủExpressibleByStringLiteral
Để tìm hiểu làm thế nào để đăng nhập thời gian biên dịch xem tại đây hoặc ở đây
Các câu trả lời tương tự khác của Rob Napier trên SO:
Tại sao bổ sung chuỗi mất quá nhiều thời gian để xây dựng?
Làm cách nào để hợp nhất nhiều Mảng mà không làm chậm trình biên dịch?
Swift Array chứa chức năng khiến thời gian xây dựng dài
var statement = "create table if not exists \(self.tableName()) (\(columns))"
?