[英]Swift string interpolation performance
在我的iOS / Swift項目中,我有很多print()
語句。 我編寫了如下的全局重寫,以便在發行版本中將其忽略:
func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
#if DEBUG
Swift.print(items, separator: separator, terminator: terminator)
#endif
}
調用print()
,有時會傳入帶有昂貴的自定義debugDescription
屬性的對象,例如:
print("Value of myArray: \(myArray)")
使用myArray
實現自定義debugDescription
如下所示:
var debugDescription: String {
get {
// Serialise the array for printing
}
}
我的問題是,在將字符串傳遞給print()
或之后會計算debugDescription
值嗎? 即#if DEBUG
預處理程序指令會從發行版本中消除計算嗎?
編輯:我知道debugDescription
是一個計算的屬性,我不確定何時調用它。 我不是我自己稱呼它。 它會在字符串插值過程中自動調用。 因此,如果Swift在將字符串傳遞給print()
之前對其進行插值,它仍會計算該屬性。 但是,如果Swift而是保存“指令”,並且僅在內部內置的Swift.print()
函數中評估字符串,那么我可以獲得性能提升。 因此,這個問題實際上是關於Swift如何處理有關性能的字符串插值。
#if DEBUG
預處理程序指令是否會從發行版本中消除計算?
不,不會。 Swift會在調用函數時評估所有函數參數。 您可以在調試器中或通過在您的debugDescription
實現中添加對Swift.print
的調用來驗證這一點。 例如,創建具有以下內容的文件:
// test.swift
struct A: CustomDebugStringConvertible {
let value: Int
var debugDescription: String {
Swift.print("Calling debugDescription")
return "A: \(value)"
}
}
func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
#if DEBUG
Swift.print(items, separator: separator, terminator: terminator)
#endif
}
let a = A(value: 42)
print("Value of a: \(a)")
然后,在終端中:
> swift test.swift
Calling debugDescription
如您所見,即使您的print
功能沒有執行任何操作,也將print
"Calling debugDescription"
(即,對debugDescription
進行評估)。 現在讓我們設置DEBUG
標志:
> swift -D DEBUG test.swift
Calling debugDescription
["Value of a: A: 42"]
這就是為什么Swift標准庫中的類似函數(例如assert
)將自動閉合用於其一個或多個參數的原因。 @autoclosure
屬性將函數參數包裝在閉包中。 這樣,被調用的函數可以決定是否以及何時對表達式求值(通過調用函數)。 這對於呼叫者是完全透明的。
不幸的是, @autoclosure
不適用於可變參數(如Any...
),所以我認為沒有一種方法可以在Swift 4.0中精確地再現您想要的內容。 但是,如果您可以使用帶有單個Any
參數的print
函數,則可以這樣定義函數:
func print(_ item: @autoclosure () -> Any, separator: String = " ", terminator: String = "\n") {
#if DEBUG
Swift.print(item(), separator: separator, terminator: terminator)
#endif
}
現在,該函數將不會計算其第一個參數,除非您調用item()
,這僅發生在#if DEBUG
塊內部,因此發行版本中沒有任何開銷。
預處理不會將#if DEBUG內部的代碼包含到發布代碼中。 因此,由於它是計算屬性,所以不用擔心,對發行代碼優化沒有影響
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.