原文鏈接: 重載 print 函數(shù)提高性能
最近項(xiàng)目準(zhǔn)備要上線(xiàn)了, 到了性能優(yōu)化的階段, 看了一些文章之后, 基本上都會(huì)提到 print
對(duì)于性能的影響很大, 常規(guī)的做法是新增一個(gè)方法, 想打印的時(shí)候全部調(diào)用這個(gè)方法, 編譯時(shí)加一個(gè)布爾判斷, 把方法里的 print 全部去掉, 變成一個(gè)空的方法, 例如下面這樣 (摘錄自 Swift 性能探索和優(yōu)化分析 -- 喵神):
// DEBUG 的 Complier Flag 的添加方法具體看喵神的的那篇文章
func dPrint(@autoclosure item: () -> Any) {
#if DEBUG
print(item())
#endif
}
dPrint(resultFromHeavyWork())
// Release 版本中 resultFromHeavyWork() 不會(huì)被執(zhí)行
但是感覺(jué)這種方式會(huì)影響代碼習(xí)慣, 而且多人協(xié)作還有認(rèn)知負(fù)擔(dān)跟溝通成本, 谷歌一下之后, 某篇文章也寫(xiě)了一樣的方法, 但是我在評(píng)論里找到了一個(gè)更加簡(jiǎn)單巧妙的方法 ---- 重載
print 是在 Swift 的標(biāo)準(zhǔn)庫(kù)里定義的, 定義如下:
public func print(items: Any..., separator: String = default, terminator: String = default)
接下來(lái)講一下我們的具體做法以及原理, 當(dāng)我們寫(xiě) Swift 代碼的時(shí)候, 我們?cè)陧?xiàng)目里定義的"全局"方法, 其實(shí)并非是真正的全局, 而是僅限于當(dāng)前的 Module 內(nèi)部, 得益于 Swift 這樣的設(shè)計(jì), 我們只要在當(dāng)前的 Module 內(nèi)部重載 print
方法就可以讓 print
變成一個(gè)空的方法了(僅限于非 DEBUG 的模式下), 具體的代碼如下:
// 注意這里是 !DEBUG
#if !DEBUG
public func print(items: Any..., separator: String = "", terminator: String = "") { }
#endif
想檢測(cè)重載是否成功的話(huà), 只要去掉布爾判斷的 !
就可以直接在電腦上看到測(cè)試效果了
不改變?nèi)魏未a習(xí)慣, 不需要溝通成本, Release 模式下自動(dòng)重載空的 print
方法, 三行代碼加上一點(diǎn)點(diǎn)設(shè)置就能完成了
不過(guò)注釋得寫(xiě)清楚, 這個(gè)重載的方法里不能加任何奇怪的東西, 要不然同事還是有可能會(huì)改掉這個(gè)方法的
但缺點(diǎn)也跟常規(guī)的方法一樣, 只能在當(dāng)前 Module 內(nèi)作用, 對(duì)于引入的第三方庫(kù)不起作用, 而且只對(duì)于 Swift 代碼有效, 但其實(shí)也無(wú)傷大雅
唯一的希望是, Swift 編譯器可以增加一個(gè)編譯模式的 flag, 而不需要我們自己去添加, 所有第三方庫(kù)也可以用這種方法去優(yōu)化性能, 但這種做法又僅限于 iOS 平臺(tái), 而且我們有可能會(huì)需要去添加自定義編譯的模式, 這種方法會(huì)帶來(lái)不必要的麻煩, 具體的做法還需要 Swift 團(tuán)隊(duì)去思考斟酌
注: 文章代碼使用的全部是 Swift 2.2 的版本
參考資料:
remove-println-for-release-version-ios-swift
swift-log-devil-or-why-println-is-dangerous(靈感來(lái)自評(píng)論區(qū) Thongchai Kolyutsakul)