Introduction to Swift Performance - Try! Swift 2016

Introduction to Swift Performance - Try! Swift 2016

8e7d17f63cb19895a31b4ba6a976e781?s=128

Danielle Tomlinson

September 01, 2016
Tweet

Transcript

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

  2. What makes code slow?

  3. Allocation

  4. Stack

  5. Heap

  6. Reference Counting

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

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

  9. Dispatch

  10. Inline (0ns)

  11. Static (~1ns)

  12. Dynamic (~5ns)

  13. Objects

  14. Classes

  15. p: Index* Stack class Index { let section: Int let

    item: Int } let i = Index(section: 1, item: 1) Heap section: Int item: Int
  16. 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*
  17. 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*
  18. Structs

  19. Stack

  20. section: 1 item: 1 Stack struct Index { let section:

    Int let item: Int } let i = Index(section: 1, item: 1)
  21. 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
  22. name: StringA* id: StringB* Stack struct User { let name:

    String let id: String } let u = User(name: "Joe", id: "1234")
  23. 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
  24. Abstractions

  25. 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() }
  26. Requirements Change

  27. Protocols

  28. 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() }
  29. Why?

  30. 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() }
  31. 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() }
  32. ProtocolWitnessTable draw() CircleDrawable ... draw() LineDrawable ...

  33. 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 ...
  34. ExistentialContainer ValueBuffer ProtocolWitnessTable

  35. ExistentialContainer radius struct Circle: Drawable { let radius: Double let

    center: Point func draw() {} } center
  36. ExistentialContainer struct Line: Drawable { let origin: Point let end:

    Point func draw() {} } Origin End
  37. 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() }
  38. None
  39. ValueWitnessTable ValueBuffer allocate: copy: destruct: deallocate:

  40. 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) }
  41. Modelling Your Data

  42. Generics

  43. struct Stack<T: Type> { ... }

  44. Enumerations

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

  46. Domain Specific Models

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