Slide 1

Slide 1 text

2017 Slow Swift

Slide 2

Slide 2 text

Marcin Krzyżanowski @krzyzanowskim PDFViewer.io pspdfkit.com github.com/krzyzanowskim CryptoSwift ObjectivePGP Natalie krzyzanowskim.com

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

1.4x

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

Script Swift? #!/usr/bin/env xcrun -sdk macosx swift print(“iOSConf.sg Rocks!”)

Slide 8

Slide 8 text

Script Swift? #!/usr/bin/env xcrun -sdk macosx swift print(“iOSConf.sg Rocks!”) -Onone 500x to 1000x slower than default optimized build

Slide 9

Slide 9 text

Compiled Swift • Optimized builds • Build times ;-(

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

Compiled Swift “Speedup AES.encrypt() compilation time from 68230.37ms to 678.34ms”

Slide 13

Slide 13 text

Source → Binary as seen…

Slide 14

Slide 14 text

Compilation SWIFT_OPTIMIZATION_LEVEL -Onone -O -O -whole-module-optimization

Slide 15

Slide 15 text

Compilation SWIFT_OPTIMIZATION_LEVEL -Onone -O -O -whole-module-optimization

Slide 16

Slide 16 text

Compilation SWIFT_DISABLE_SAFETY_CHECKS Disable runtime safety checks when optimizing.

Slide 17

Slide 17 text

Compilation SWIFT_ENFORCE_EXCLUSIVE_ACCESS full compile-time none (SE-0176)

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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)

Slide 21

Slide 21 text

Source Optimization • Can be optimized to pass-by-value • Pointers are useful for performance In-Out Parameters

Slide 22

Slide 22 text

Source Optimization Obvious • struct over class • final class • private final class

Slide 23

Slide 23 text

Source Optimization non-Obvious 2.7s

Slide 24

Slide 24 text

Source Optimization non-Obvious

Slide 25

Slide 25 text

Source Optimization non-Obvious 1.2s 2.7s

Slide 26

Slide 26 text

Source Optimization • for-loop over map • for-loop over reduce • transformation over the dictionary with reduce may end up with O(n2)

Slide 27

Slide 27 text

Source Optimization 0.9s

Slide 28

Slide 28 text

Source Optimization 0.8s

Slide 29

Slide 29 text

Source Optimization Inlining

Slide 30

Slide 30 text

Source Optimization Inlining • Automatic inlining (SIL, LLVM)

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

Memory

Slide 36

Slide 36 text

Memory

Slide 37

Slide 37 text

Memory • What if…. raw chunk of memory (Unmanaged) • allocate buffer • deallocate buffer • no ARC, no COW, nothing

Slide 38

Slide 38 text

Memory

Slide 39

Slide 39 text

Array() turns out to be nearly 10% slower compared to UnsafeMutablePointer.allocate(capacity:) Memory

Slide 40

Slide 40 text

Memory Stack free space Heap Static data Literals Instructions 0x000000 0xFFFFFF

Slide 41

Slide 41 text

Memory Stack free space Heap Static data Literals Instructions • Stack allocation - fast (%rsp)

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Quiz

Slide 46

Slide 46 text

Allocation Stack free space Heap Static data Literals Instructions

Slide 47

Slide 47 text

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 }

Slide 48

Slide 48 text

Allocation Stack free space Heap Static data Literals Instructions

Slide 49

Slide 49 text

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 }

Slide 50

Slide 50 text

Allocation Stack free space Heap Static data Literals Instructions

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

Generics

Slide 53

Slide 53 text

–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.”

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

Generics

Slide 56

Slide 56 text

Generics 0.20s

Slide 57

Slide 57 text

Generics

Slide 58

Slide 58 text

Generics 0.06s 0.20s

Slide 59

Slide 59 text

Generics

Slide 60

Slide 60 text

Generics

Slide 61

Slide 61 text

Generics

Slide 62

Slide 62 text

Generics & Optimization • Automatic specialization

Slide 63

Slide 63 text

Generics & Optimization • Automatic specialization • in the same module

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

Let's Recap…

Slide 69

Slide 69 text

Let's Recap… Debug is slow

Slide 70

Slide 70 text

Pre-allocate memory Let's Recap…

Slide 71

Slide 71 text

Let's Recap… Stack vs Heap

Slide 72

Slide 72 text

Let's Recap…Copy is bad

Slide 73

Slide 73 text

Let's Recap… Use carefully

Slide 74

Slide 74 text

Let's Recap… Less Swift is faster Swift

Slide 75

Slide 75 text

@krzyzanowskim krzyzanowskim.com Thank you!