為什么Swift比OC快栏渺?

Dispatch

親俏脊,我的簡書已不再維護(hù)和更新了戒幔,所有文章都遷移到了我的個人博客:https://mikefighting.github.io/拌喉,歡迎交流派诬。

Swift相比OC以及其它語言盟萨,有很多的優(yōu)化點吝羞,這篇文章將從方法調(diào)度的角度去說明為什么Swift要比OC更快兰伤。OC是一門動態(tài)的語言,很多實際執(zhí)行需要在運行時才可以確定钧排,Swift不一樣敦腔,Swift將很多在運行時才可以確定的信息,在編譯期就決定了恨溜。這就讓Swift更加快速符衔。
方法調(diào)度就是程序在觸發(fā)方法時選擇需要執(zhí)行指令的過程,它在每次方法執(zhí)行時都會發(fā)生糟袁。如果這種調(diào)度發(fā)生在編譯期判族,我們稱它為靜態(tài)調(diào)度(Static Dispatch),如果調(diào)度發(fā)生在運行時项戴,那么我們稱它為動態(tài)調(diào)度(Dynamic Dispatch)形帮。靜態(tài)調(diào)度往往要比動態(tài)調(diào)度要快。那么問題來了,為什么我們需要動態(tài)調(diào)度呢辩撑?全部用靜態(tài)調(diào)度不就得了界斜?
問題就在于我們很多時候我們需要用到多態(tài),看看下面這段非常簡單的代碼

class Animal {

    func eat() {
        print("animal eat");
    }
    func sleep() {
        print("animal sleep")
    }
}

class Dog: Animal {

    override func sleep() {
        print("dog sleep")
    }
}

class Rabbit: Animal {
    
    override func eat() {
        print("rabbit sleep");
    }
   override func sleep() {
        print("rabbit sleep")
    }
    
}
var animal:Animal?
var somThingTrue = false
//執(zhí)行很多業(yè)務(wù)邏輯
if somThingTrue {
    animal = Rabbit()
    
}else{

    animal = Dog()
}
animal?.eat()

上面的代碼中animal?.eat()就不能夠在編譯期確定合冀,因為其中需要很多的業(yè)務(wù)邏輯(比如根據(jù)用戶的不同各薇,或者網(wǎng)絡(luò)請求結(jié)果的不同)來確定就究竟創(chuàng)建出來的對象是Rabbit還是Dog,也就無法最終確定要調(diào)用那個對象的eat()方法君躺。相似的代碼在OC中是怎樣執(zhí)行的呢峭判?在OC中編譯器會將這個方法翻譯成objc_msgSend(target,@selector(eat),nil)這個方法,然后到了運行時棕叫,會分為以下幾步進(jìn)行調(diào)用:

  1. 找到方法target中isa對應(yīng)的Class(如果是類方法要到其metaClass中找)朝抖。
  2. 從其中的struct objc_method_list **methodLists找到對應(yīng)的方法實現(xiàn)。
  3. 如果沒有找到就到superClass的methodLists中找谍珊。

如果在Swift中治宣,它是怎樣做方法調(diào)度的呢?

  1. 找到target對應(yīng)的class

  2. 從class的V-Table中的那得到函數(shù)的實現(xiàn)
    Swift中的類會創(chuàng)建一個V-Table砌滞,這個Table是一個數(shù)組侮邀,其中存放的是函數(shù)指針。子類會按照父類V-Table中函數(shù)的存放贝润,如果子類沒有覆蓋某個方法绊茧,那么就會拷貝父類方法的地址,如上面的例子會得到下面的V-Table打掘。

    Animal

    Index0 eat 0x0001
    Index1 sleep 0x0004

    Dog

    Index0 eat 0x0001 (copied)
    Index1 sleep 0x0008 (overrideen)

    Rabbit

    Index0 eat 0x0002 (overrideen)
    Index1 sleep 0x0003 (overrideen)

可以注意到Dog因為沒有覆蓋父類的eat方法华畏,所以其copy了父類的0x0010指針。因為Swift是Type Safe的尊蚁,所以在調(diào)用它的時候它不會變成Robot或者其它的類(如果不能通過編譯)亡笑,所以無論是調(diào)用上面結(jié)構(gòu)中的Animal,Dog横朋,還是Rabbit類仑乌,它都是調(diào)用相同的Index,得到對應(yīng)的方法實現(xiàn)琴锭。將函數(shù)指針和Index所做的映射在編譯期就確定了晰甚,這就大大減少了運行時的工作量,提高了運行速度决帖。所以在運行時它沒有必要知道是哪個類型的實例調(diào)用了這個方法厕九,只需要找到相應(yīng)的V-Table即可,至于是其中的哪個Index已經(jīng)在編譯期確定了地回,沒必要再去查找Index的值扁远。
然而Swift的方法調(diào)度不僅僅是動態(tài)方法調(diào)度腺阳,還有很多靜態(tài)方法調(diào)度。
如果我們將某個方法標(biāo)記為final或者private穿香,或者我們不用類亭引,而使用結(jié)構(gòu)體,枚舉皮获,這時就不需要動態(tài)調(diào)度焙蚓,只需要靜態(tài)調(diào)度即可,這樣速度會更快洒宝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末购公,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子雁歌,更是在濱河造成了極大的恐慌宏浩,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件靠瞎,死亡現(xiàn)場離奇詭異比庄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)乏盐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進(jìn)店門佳窑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人父能,你說我怎么就攤上這事神凑。” “怎么了何吝?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵溉委,是天一觀的道長。 經(jīng)常有香客問我爱榕,道長瓣喊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任呆细,我火速辦了婚禮型宝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘絮爷。我一直安慰自己,他們只是感情好梨树,可當(dāng)我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布坑夯。 她就那樣靜靜地躺著,像睡著了一般抡四。 火紅的嫁衣襯著肌膚如雪柜蜈。 梳的紋絲不亂的頭發(fā)上仗谆,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天,我揣著相機(jī)與錄音淑履,去河邊找鬼隶垮。 笑死,一個胖子當(dāng)著我的面吹牛秘噪,可吹牛的內(nèi)容都是我干的狸吞。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼指煎,長吁一口氣:“原來是場噩夢啊……” “哼蹋偏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起至壤,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤威始,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后像街,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體黎棠,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年镰绎,在試婚紗的時候發(fā)現(xiàn)自己被綠了葫掉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡跟狱,死狀恐怖俭厚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情驶臊,我是刑警寧澤挪挤,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站关翎,受9級特大地震影響扛门,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纵寝,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一论寨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爽茴,春花似錦葬凳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至胧沫,卻和暖如春昌简,著一層夾襖步出監(jiān)牢的瞬間占业,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工纯赎, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留谦疾,地道東北人。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓犬金,卻偏偏與公主長得像念恍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子佑附,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 2014年的蘋果全球開發(fā)者大會(WWDC)樊诺,當(dāng)Craig Federighi向全世界宣布“We have new ...
    yeshenlong520閱讀 2,295評論 0 9
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件音同、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,125評論 4 61
  • 早上好词爬,我的朋友, 星期一权均,又是充滿希望的一周顿膨, 又是令人清新的早晨, 春光無限好叽赊,花香也多情恋沃, 在這美好的季節(jié)里...
    b5b368f85346閱讀 177評論 0 0
  • 文/親一親太陽 光著腳丫小溪里捉水花 蝦兒螃蟹小魚過家家岸邊的麻雀嘰嘰喳 她說天上的彩虹跑到了水里耍 稀奇稀奇真稀...
    親一親太陽閱讀 288評論 6 5
  • 二、初見 最初的生命安靜沉睡必指, 一絲不掛的靈魂囊咏, 落入潔白無瑕的肉軀。 真切的黎明迎來涼意塔橡, 細(xì)細(xì)絲絲梅割,纏住了 上...
    石莨閱讀 191評論 0 1