Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to Swift Performance - Try! Swift 2016

Introduction to Swift Performance - Try! Swift 2016

Danielle Tomlinson

September 01, 2016
Tweet

More Decks by Danielle Tomlinson

Other Decks in Programming

Transcript

  1. An Introduction to
    Swift Performance
    Danielle Tomlinson - @dantoml

    View full-size slide

  2. What makes code slow?

    View full-size slide

  3. Reference Counting

    View full-size slide

  4. func perform(with object: Object) {
    object.doAThing()
    }

    View full-size slide

  5. func perform(with object: Object) {
    __swift_retain(object)
    object.doAThing()
    __swift_release(object)
    }

    View full-size slide

  6. Inline (0ns)

    View full-size slide

  7. Static (~1ns)

    View full-size slide

  8. Dynamic (~5ns)

    View full-size slide

  9. p: Index*
    Stack
    class Index {
    let section: Int
    let item: Int
    }
    let i = Index(section: 1,
    item: 1)
    Heap
    section: Int
    item: Int

    View full-size slide

  10. i: Index*
    Stack
    class Index {
    let section: Int
    let item: Int
    }
    let i = Index(section: 1,
    item: 1)
    let i2 = i
    Heap
    section: Int
    item: Int
    i2: Index*

    View full-size slide

  11. i: Index*
    Stack
    class Index {
    let section: Int
    let item: Int
    }
    let i = Index(section: 1,
    item: 1)
    __swift_retain(i)
    let i2 = i
    Heap
    section: Int
    item: Int
    i2: Index*

    View full-size slide

  12. section: 1
    item: 1
    Stack
    struct Index {
    let section: Int
    let item: Int
    }
    let i = Index(section: 1, item: 1)

    View full-size slide

  13. Stack
    struct Index {
    let section: Int
    let item: Int
    }
    let i = Index(section: 1, item: 1)
    let i2 = i
    section: 1
    item: 1
    section: 1
    item: 1

    View full-size slide

  14. name: StringA*
    id: StringB*
    Stack
    struct User {
    let name: String
    let id: String
    }
    let u = User(name: "Joe", id: "1234")

    View full-size slide

  15. name: StringA*
    id: StringB*
    Stack
    name: StringA*
    id: StringB*
    struct User {
    let name: String
    let id: String
    }
    let u = User(name: "Joe",
    id: "1234")
    __swift_retain(u.name._textStorage)
    __swift_retain(u.id._textStorage)
    let u2 = u

    View full-size slide

  16. Abstractions

    View full-size slide

  17. Example (0.3s)
    :
    struct Circle {
    let radius: Double
    let center: Point
    func draw() {}
    }
    var circles = (1..<100_000_000).map { _ in Circle(...) }
    for circle in circles {
    circle.draw()
    }

    View full-size slide

  18. Requirements Change

    View full-size slide

  19. Example (4s)
    :
    protocol Drawable {
    func draw()
    }
    struct Circle: Drawable {
    let radius: Double
    let center: Point
    func draw() {}
    }
    let drawables: [Drawable] = (1..<100_000_000).map { _ in Circle(...) }
    for drawable in drawables {
    drawable.draw()
    }

    View full-size slide

  20. struct Circle {
    let radius: Double
    let center: Point
    func draw() {}
    }
    var circles = (1..<100_000_000).map { _ in Circle(...) }
    for circle in circles {
    circle.draw()
    }

    View full-size slide

  21. protocol Drawable {
    func draw()
    }
    struct Circle: Drawable {
    let radius: Double
    let center: Point
    func draw() {}
    }
    var drawables: [Drawable] = (1..<100_000_000).map { _ in return Circle(...) }
    for drawable in drawables {
    drawable.draw()
    }

    View full-size slide

  22. ProtocolWitnessTable
    draw()
    CircleDrawable
    ...
    draw()
    LineDrawable
    ...

    View full-size slide

  23. protocol Drawable {
    func draw()
    }
    struct Circle: Drawable {
    let radius: Double
    let center: Point
    func draw() {}
    }
    var drawables: [Drawable] = (1..<100_000_000).map { _ in
    return Circle(...)
    }
    for drawable in drawables {
    drawable.draw()
    }
    draw()
    CircleDrawable
    ...

    View full-size slide

  24. ExistentialContainer
    ValueBuffer
    ProtocolWitnessTable

    View full-size slide

  25. ExistentialContainer
    radius
    struct Circle: Drawable {
    let radius: Double
    let center: Point
    func draw() {}
    }
    center

    View full-size slide

  26. ExistentialContainer
    struct Line: Drawable {
    let origin: Point
    let end: Point
    func draw() {}
    }
    Origin
    End

    View full-size slide

  27. Example (45s)
    :
    protocol Drawable {
    func draw()
    }
    struct Line: Drawable {
    let origin: Point
    let end: Point
    func draw() {}
    }
    let drawables: [Drawable] = (1..<100_000_000).map { _ in Line(...) }
    for drawable in drawables {
    drawable.draw()
    }

    View full-size slide

  28. ValueWitnessTable
    ValueBuffer
    allocate:
    copy:
    destruct:
    deallocate:

    View full-size slide

  29. In Practice
    Stack
    origin
    Line
    vwt
    pwt
    end
    LineDrawable
    copy:
    ...
    Heap
    drawable:
    func draw(drawable: Drawable) {
    drawable.draw()
    }
    let value: Drawable = Line()
    draw(local: value)
    // Generates
    func draw(value: ECTDrawable) {
    var drawable: ECTDrawable = ECTDrawable()
    let vwt = value.vwt
    let pwt = value.pwt
    drawable.vwt = value.vwt
    drawable.pwt = value.pwt
    vwt.allocateBuffAndCopyValue(&drawable, value)
    pwt.draw(vwt.projectBuffer(&drawable)
    }

    View full-size slide

  30. Modelling Your Data

    View full-size slide

  31. struct Stack {
    ...
    }

    View full-size slide

  32. Enumerations

    View full-size slide

  33. enum AccountStatus: String, RawRepresentable {
    case .banned, .verified, incomplete
    }

    View full-size slide

  34. Domain Specific Models

    View full-size slide

  35. Thanks!
    Office Hours: 16:30 in the Atrium. @dantoml

    View full-size slide