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

Slow Swift

Slow Swift

Exploring Swift runtime performance. Singapore 2017. http://iOSConf.sg

Video: https://www.youtube.com/watch?v=G88qaR9R0v0

Marcin Krzyzanowski

October 20, 2017
Tweet

More Decks by Marcin Krzyzanowski

Other Decks in Programming

Transcript

  1. –Waldi Ravens “A Objective- (red.) C program is like a

    fast dance on a newly waxed dance floor by people carrying razors.” Why Swift?
  2. –Waldi Ravens “A Objective- (red.) C program is like a

    fast dance on a newly waxed dance floor by people carrying razors.” Why Swift?
  3. Compiled Swift • Optimized builds • Build times ;-( let

    arr: [Int] = [1] + [2] + [3] + [4] + [5] + [6]
  4. Compiled Swift • Optimized builds • Build times ;-( let

    arr: [Int] = [1] + [2] + [3] + [4] + [5] + [6] Expression is too complex to be solved in reasonable time
  5. Compilation GCC_GENERATE_DEBUGGING_SYMBOLS The shortcuts taken by optimized code may occasionally

    produce surprising results: some variables you declared may not exist at all
  6. Source Optimization • &+ and &- and &* but +

    and - and * • discarding any overflow (~~SWIFT_DISABLE_SAFETY_CHECKS) • init(truncatingIfNeeded:) • init(truncatingBitPattern:) no longer public ;-) • private init(_truncatingBits:) uses Builtin.truncOrBitCast
  7. Source Optimization In-Out Parameters –Swift Programming Language “An inout parameter

    has a value that is passed in to the function, is modified by the function, and is passed back out of the function to replace the original value.” func core(block: inout Array<UInt8>)
  8. Source Optimization • Can be optimized to pass-by-value • Pointers

    are useful for performance In-Out Parameters
  9. Source Optimization • for-loop over map • for-loop over reduce

    • transformation over the dictionary with reduce may end up with O(n2)
  10. Source Optimization Inlining • Automatic inlining (SIL, LLVM) • Inline

    all the things with @inline(__always) • Force inlining with @_transparent
  11. Source Optimization Inlining • Automatic inlining (SIL, LLVM) • Inline

    all the things with @inline(__always) • Force inlining with @_transparent • Public interface @_inlineable
  12. Source Optimization Inlining • Automatic inlining (SIL, LLVM) • Inline

    all the things with @inline(__always) • Force inlining with @_transparent • Public interface @_inlineable • Be careful with ABI and public API
  13. Memory • What if…. raw chunk of memory (Unmanaged) •

    allocate buffer • deallocate buffer • no ARC, no COW, nothing
  14. Array<UInt8>() turns out to be nearly 10% slower compared to

    UnsafeMutablePointer<UInt8>.allocate(capacity:) Memory
  15. Memory Stack free space Heap Static data Literals Instructions •

    Stack allocation - fast (%rsp) • Heap allocation - slow (slower) (syscalls)
  16. Memory Stack free space Heap Static data Literals Instructions •

    Stack allocation - fast (%rsp) • Heap allocation - slow (slower) (syscalls) • Preallocation
  17. Memory Stack free space Heap Static data Literals Instructions •

    Stack allocation - fast (%rsp) • Heap allocation - slow (slower) (syscalls) • Preallocation • array.reserveCapacity(1024)
  18. Allocation Stack free space Heap Static data Literals Instructions (lldb)

    register read rsp rsp = 0x00007fff5fbff630 (lldb) frame variable -L 0x00007fff5fbff658: ([Int]) array = 3 values { 0x00007fa5391de610: [0] = 0 0x00007fa53e6bf3f0: [1] = -1 0x00007fa53e6a91d0: [2] = 1 }
  19. Allocation Stack free space Heap Static data Literals Instructions (lldb)

    register read rsp rsp = 0x000070000ec06c00 (lldb) fr variable -L 0x000070000ec06c18: (@lvalue [Int]) array = 0x0000000100d002b0: { 0x0000000100d002b0: &array = 2 values { 0x00007fd7df41ae10: [0] = 0 0x00007fd7df485c90: [1] = -1 0x00007fd7df4829b0: [2] = 1 }
  20. Allocation Stack free space Heap Static data Literals Instructions (lldb)

    register read rsp rsp = 0x000070000ec06c00 (lldb) fr variable -L 0x00007fff5fbff680: (@lvalue MyStruct) s = 0x0000000100f06820: { 0x0000000100f06820: &s = { 0x0000000100f06820: value = "test" } }
  21. –who knows “Generic code enables you to write flexible, reusable

    functions and types that can work with any type, subject to requirements that you define.”
  22. Generics & Optimization • Automatic specialization • in the same

    module • otherwise use @_specialize(exported: true, where T == Int)
  23. Generics & Optimization • Automatic specialization • in the same

    module • otherwise use @_specialize(exported: true, where T == Int) • Whole Module Optimization won’t help
  24. Generics & Optimization • Automatic specialization • in the same

    module • otherwise use @_specialize(exported: true, where T == Int) • Whole Module Optimization won’t help • Sometimes it won’t optimize for the same module
  25. Generics & Optimization • Automatic specialization • in the same

    module • otherwise use @_specialize(exported: true, where T == Int) • Whole Module Optimization won’t help • Sometimes it won’t optimize for the same module • Avoid generics in public API