Swift开源之编写高性能代码(更新版)

作者: Fosen波波 | 来源:发表于2015-12-05 20:02 被阅读454次

    小伙伴们,swift开源啦!

    <Writing High-Performance Swift Code>中的信息会给我们的开发带来很多实用性的建议。

    一、降低动态调度

    1.动态调度

    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 = ...
    }
    

    2.使用'final'时,声明并不需要被重写

    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.
    }
    

    3.使用'private'时,在本类之外其声明并不需要访问

    private class E {
    func doSomething() { ... }
    }
    
    >class F {
    private 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 A’s doSomething method.
    }
    
    >func usingF(f: F) -> Int {
    return f.myPrivateVar
    }
    

    二、高效使用容器类型

    1.数组中使用值类型

    // Don't use a class here.
    struct PhonebookEntry {
    var name : String
    var number : [Int]
    }
    var a : [PhonebookEntry]
    

    2.在不需要NSArray桥接时,使用ContiguousArray作为参考类型

    class C { ... }var a: ContiguousArray= [C(...), C(...), ..., C(...)]
    

    3.必要时,可以使用NSArray代替对象

    var c: [Int] = [ ... ]
    var d = c        // No copy will occur here.
    d.append(2)      // A copy *does* occur here.
    
    func append_one(a: [Int]) -> [Int] {
    a.append(1)
    return a
    }
    var a = [1, 2, 3]
    a = append_one(a)
    
    func append_one_in_place(inout a: [Int]) {
    a.append(1)
    }
    var a = [1, 2, 3]
    append_one_in_place(&a)
    

    三、未检查操作

    使用未经检查的整数运算时,就能判断不可能发生溢出

    a : [Int]
    b : [Int]
    c : [Int]
    // Precondition: for all a[i], b[i]: a[i] + b[i] does not overflow!
    for i in 0 ... n {
    c[i] = a[i] &+ b[i]
    }
    

    四、泛型

    如例:

    class MySwiftFunc{ ... }MySwiftFuncX     // Will emit code that works with Int...MySwiftFuncY               // ... as well as String.
    class MyStack{
    func push(element: T) { ... }
    func pop() -> T { ... }
    }
    
    func myAlgorithm(a: [T], length: Int) { ... }
    // The compiler can specialize code of MyStack[Int]
    var stackOfInts: MyStack[Int]
    // Use stack of ints.
    for i in ... {
    stack.push(...)
    stack.pop(...)
    }
    
    var arrayOfInts: [Int]
    // The compiler can emit a specialized version of 'myAlgorithm' targeted for
    // [Int]' types.
    myAlgorithm(arrayOfInts, arrayOfInts.length)
    

    1.在同一个文件中它们可以被用于一些通用声明

    2.允许编译器执行一些通用序列化

    //Framework.swift:
    protocol Pingable { func ping() -> Self }
    protocol Playable { func play() }
    extension Int : Pingable {  
            func ping() -> Int { return self + 1 }
    
    class Game: Playable {  
    var t : T  init (_ v : T) {t = v}  
    func play() {    
            for _ in 0...100_000_000 { t = t.ping() } 
     }
    }
    
    func play_a_game(game : Playable ) {  
               // This check allows the optimizer to specialize the  
               // generic call 'play'  
          if let z = game as? Game{
                z.play()
          } else {
               game.play() }
         }
    /// -------------- >8
    // Application.swift:
    play_a_game(Game(10))
    

    五、Swift的较大值

     protocol P {}
    struct Node : P {
    var left, right : P?
    }
    
    >struct Tree {
    var node : P?
    init() { ... }
    }
    

    使用copy-on-write语义来处理较大值

    struct tree : P {
    var node : [P?]
    init() {
    node = [ thing ]
    }
    }
    
    final class Ref{   
             var val : T  init(_ v : T) {val = v}
    }
    struct Box{    
            var ref : Refinit(_ x : T) { ref = Ref(x) }
            var value: T {
            get { return ref.val }
            set {
                    if (!isUniquelyReferencedNonObjC(&ref)) {
                    ref = Ref(newValue)
                    return       }
            ref.val = newValue}
    }
    }
    
    <The type Box can replace the array in the code sample above>
    

    六、代码的安全

    example:
    final class Node {
    var next: Node?
    var data: Int
    ...
    }
    

    使用非引用,以避免引用计数'开支'

    var Ref : Unmanaged= Unmanaged.passUnretained(Head)
    while let Next = Ref.takeUnretainedValue().next {
    ...
    Ref = Unmanaged.passUnretained(Next)
    }
    

    七、协议

    标记的协议只能满足固定那个类的协议

    protocol Pingable : class { func ping() -> Int }
    
    

    注:以上是个人读取相关文档的理解,仅供大家学习使用。

    相关文章

      网友评论

      • WyattWang:简书支持Markdown语法,对于文章中的代码部分,可以使用这用方式来实现,而非引用。
        ```
        code
        ```
        WyattWang:@Swift波波 你给的这种是引用,这样代码的缩进、高亮效果都没有了。
        Fosen波波:@WyattWang 恩,我只是感觉给相对应的标记即可嘛😊

      本文标题:Swift开源之编写高性能代码(更新版)

      本文链接:https://www.haomeiwen.com/subject/kuoshttx.html