swift 比oc更快,但是swift編譯比oc時(shí)間長(zhǎng)
因?yàn)閟wift使用Whole Module Optimizations
優(yōu)化機(jī)制
swift值類型存儲(chǔ)在棧中博杖,引用類型存儲(chǔ)在堆中筷登。
1、棧是線程獨(dú)有的狈醉,因此不需要考慮線程安全問(wèn)題苗傅。
2莺匠、堆中的數(shù)據(jù)是多線程共享的,所以為了防止線程不安全摇庙,需同步鎖來(lái)解決這個(gè)問(wèn)題題
Objective-C語(yǔ)言動(dòng)態(tài)化(runtime)這種靈活性是以查表的方式找出函數(shù)地址卫袒,既然查表操作单匣,當(dāng)然要付出時(shí)間代價(jià)
對(duì)象基于協(xié)議
Existential Container
協(xié)議類型
:一般的Existential Container
數(shù)據(jù)結(jié)構(gòu)為:
- 數(shù)組中每個(gè)元素的大小都是固定的 5 個(gè) word户秤,解決了數(shù)組元素下標(biāo)快速定位的問(wèn)題。
- 因?yàn)橛?Value Buffer 的存在转砖,我們可以將不同大小的值類型存放到 Value Buffer 中府蔗,小于等于 3 個(gè) word 的值直接存儲(chǔ)汞窗,更大的則通過(guò)保存引用地址的方式存儲(chǔ)。
- 通過(guò) Value Witness Table不铆,我們可以找到這個(gè)值類型的相關(guān)生命周期的管理函數(shù)。
- 通過(guò) Protocol Witness Table狂男,我們可以找到協(xié)議的具體實(shí)現(xiàn)函數(shù)的地址。
編譯優(yōu)化
Clang 編譯器流程
image.png
swift 特有編譯器流程
image.png
注釋:AST
: 抽象語(yǔ)法樹
- 預(yù)處理(Pre-process):他的主要工作就是將宏替換红碑,刪除注釋展開頭文件泡垃,生成.i文件。
- 詞法分析 (Lexical Analysis):將代碼切成一個(gè)個(gè) token忠寻,比如大小括號(hào),等于號(hào)還有字符串等奕剃。是計(jì)算機(jī)科學(xué)中將字符序列轉(zhuǎn)換為標(biāo)記序列的過(guò)程纵朋。
- 語(yǔ)法分析(Semantic Analysis):驗(yàn)證語(yǔ)法是否正確,然后將所有節(jié)點(diǎn)組成抽象語(yǔ)法樹 AST 茄袖。由 Clang 中 Parser 和 Sema 配合完成
- 靜態(tài)分析(Static Analysis):使用它來(lái)表示用于分析源代碼以便自動(dòng)發(fā)現(xiàn)錯(cuò)誤操软。
- 中間代碼生成(Code Generation):開始IR中間代碼的生成了,CodeGen 會(huì)負(fù)責(zé)將語(yǔ)法樹自頂向下遍歷逐步翻譯成 LLVM IR宪祥,IR 是編譯過(guò)程的前端的輸出后端的輸入聂薪。
- 優(yōu)化(Optimize):LLVM 會(huì)去做些優(yōu)化工作,在 Xcode 的編譯設(shè)置里也可以設(shè)置優(yōu)化級(jí)別-01蝗羊,-03藏澳,-0s,還可以寫些自己的 Pass耀找,官方有比較完整的 Pass 教程: Writing an LLVM Pass — LLVM 5 documentation 翔悠。如果開啟了 bitcode 蘋果會(huì)做進(jìn)一步的優(yōu)化,有新的后端架構(gòu)還是可以用這份優(yōu)化過(guò)的 bitcode 去生成涯呻。
- 生成目標(biāo)文件(Assemble):生成Target相關(guān)Object(Mach-o)
- 鏈接(Link):生成 Executable 可執(zhí)行文件
Swift可以通過(guò)關(guān)鍵字dynamic
對(duì)方法進(jìn)行標(biāo)記凉驻,這樣就會(huì)告訴編譯器腻要,此方法使用的是OC的運(yùn)行時(shí)機(jī)制。
注意:我們常見(jiàn)的關(guān)鍵字@ObjC
并不會(huì)改變Swift原有的方法分派機(jī)制乱投,關(guān)鍵字@ObjC
的作用只是告訴編譯器剑刑,該段代碼對(duì)于OC可見(jiàn)。
Class extension使用的是Static dispatch