<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          編寫高性能 Swift - 減少動(dòng)態(tài)分發(fā)的三條建議

          共 2625字,需瀏覽 6分鐘

           ·

          2021-03-25 15:43

          高性能代碼是每個(gè)開發(fā)工程師應(yīng)有的追求。

          在 Swift 官方 Github 上,官方整理了一些編寫高性能 Swift 代碼的技巧,這些技巧可以幫助提高您的Swift程序的質(zhì)量,并使代碼更不易出錯(cuò),更易讀。值得我們好好研讀。

          小集后續(xù)會(huì)陸續(xù)整理這些內(nèi)容,同時(shí)也會(huì)搜集這一類的好文章,期望能給 Swifter 帶來(lái)幫助。

          Swift 與 Objective-C 一樣,是一種高度動(dòng)態(tài)化的語(yǔ)言。不過(guò)與 Objective-C 不同的是,Swift 能夠在必要時(shí)通過(guò)消除或減少這種動(dòng)態(tài)性來(lái)提高運(yùn)行時(shí)性能。本節(jié)將介紹幾個(gè)可用于執(zhí)行這類操作的語(yǔ)言構(gòu)造。

          動(dòng)態(tài)分發(fā)

          默認(rèn)情況下,Swift 中類的方法和屬性訪問(wèn)使用動(dòng)態(tài)分發(fā)的方式。因此,在下面的代碼段中,a.aProperty、a.doSomething() 和 a.doSomethingElse() 都是通過(guò)動(dòng)態(tài)分發(fā)來(lái)調(diào)用的。

          class A {
          var aProperty: [Int]
          func doSomething() { ... }
          dynamic doSomethingElse() { ... }
          }

          class B: A {
          override var aProperty {
          get { ... }
          set { ... }
          }

          override func doSomething() { ... }
          }

          func usingAnA(_ a: A) {
          a.doSomething()
          a.aProperty = ...
          }

          在 Swift 中,動(dòng)態(tài)分發(fā)默認(rèn)通過(guò) vtable 來(lái)間接調(diào)用。如果在聲明中附加 dynamic 關(guān)鍵字,那么 Swift 將以 Objective-C 消息分發(fā)機(jī)制來(lái)發(fā)出調(diào)用。這兩種情況都比直接函數(shù)調(diào)用的方式慢,因?yàn)樗鼈兂藞?zhí)行間接調(diào)用本身的開銷外,還阻止了許多編譯器優(yōu)化。

          所以,在對(duì)性能很敏感的應(yīng)用中,我們通常會(huì)希望限制這種動(dòng)態(tài)行為。

          建議1:當(dāng)知道不需要重寫聲明時(shí),請(qǐng)使用 final

          final 關(guān)鍵字是對(duì)類、方法或?qū)傩缘穆暶鞯南拗?,以使聲明不能被覆蓋。這意味著編譯器可以使用直接函數(shù)調(diào)用,而不是間接調(diào)用。例如,在下面的示例中,將直接訪問(wèn) C.array1 和 D.array1。相比之下,D.array2 將通過(guò) vtable 進(jìn)行調(diào)用:

          final class C {
          // No declarations in class 'C' can be overridden.
          var array1: [Int]
          func doSomething() { ... }
          }

          class D {
          final var array1: [Int] // 'array1' cannot be overridden by a computed property.
          var array2: [Int] // 'array2' *can* be overridden by a computed property.
          }

          func usingC(_ c: C) {
          c.array1[i] = ... // Can directly access C.array without going through dynamic dispatch.
          c.doSomething() = ... // Can directly call C.doSomething without going through virtual dispatch.
          }

          func usingD(_ d: D) {
          d.array1[i] = ... // Can directly access D.array1 without going through dynamic dispatch.
          d.array2[i] = ... // Will access D.array2 through dynamic dispatch.
          }

          建議2:當(dāng)不需要在文件外部訪問(wèn)聲明時(shí),請(qǐng)使用 private 和 fileprivate

          將 private 或 fileprivate 關(guān)鍵字應(yīng)用于聲明會(huì)將聲明的可見性限制在文件中。這讓編譯器能夠確定所有其他可能覆蓋的聲明。因此,如果文件中沒(méi)有任何重寫的聲明,那么編譯器能夠自動(dòng)推斷并使用 final 關(guān)鍵字,并相應(yīng)地刪除對(duì)方法和字段訪問(wèn)的間接調(diào)用。例如,在下面的示例中,假設(shè) E,F(xiàn) 在同一文件中沒(méi)有任何重寫的聲明,則可以直接訪問(wèn) e.doSomething() 和 f.myPrivateVar:

          private class E {
          func doSomething() { ... }
          }

          class F {
          fileprivate var myPrivateVar: Int
          }

          func usingE(_ e: E) {
          e.doSomething() // There is no sub class in the file that declares this class.
          // The compiler can remove virtual calls to doSomething()
          // and directly call E's doSomething method.
          }

          func usingF(_ f: F) -> Int {
          return f.myPrivateVar
          }

          建議3:如果啟用了 WMO,則當(dāng)不需要在模塊外部訪問(wèn)聲明時(shí),請(qǐng)使用 internal

          WMO 讓編譯器一次編譯所有模塊的源代碼。這使優(yōu)化器在編譯單個(gè)聲明時(shí)具有模塊范圍的可見性。由于內(nèi)部聲明在當(dāng)前模塊之外不可見,因此優(yōu)化器可以通過(guò)自動(dòng)發(fā)現(xiàn)所有可能重寫的聲明來(lái)推斷出 final。

          注意:由于在 Swift 中默認(rèn)訪問(wèn)控制級(jí)別始終是 internal,因此通過(guò)啟用“整體模塊優(yōu)化”,無(wú)需進(jìn)行任何其他工作即可獲得更多的虛擬化功能。

          瀏覽 72
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  俺来也亚洲欧美 | 天天操天天射天天好逼网 | 狠狠撸 | 在线亚洲免费视频二 | 欧美成人精品一二三区欧美风情 |