Slide 1

Slide 1 text

More Swift App Startup Time @giginet

Slide 2

Slide 2 text

@giginet • iOS Engineer @ Cookpad • ։ൃج൫΍ͬͯ·͢ • झຯɿήʔϜ։ൃ • Contributor of fastlane

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Agenda • ࠔ͍ͬͯΔ͜ͱ • Dynamic Linkerͱdyld 3 • LabͰฉ͍ͨ͜ͱ • ىಈ࣌ؒͷޮՌతͳܭଌํ๏ • LabͰੜ͖࢒Δʹ͸

Slide 5

Slide 5 text

ࠔ͍ͬͯΔ͜ͱ • Dynamic Framework͕஗͍໰୊

Slide 6

Slide 6 text

ࠔ͍ͬͯΔ͜ͱ • SwiftͷϥΠϒϥϦ͸Dynamic Frameworkͱͯ͠Ϧϯ Ϋ͞ΕΔ • Carthage • CocoaPods(use_frameworks!) • ૿΍͢ͱىಈ͕஗͘ͳΔ • ؀ڥʹΑͬͯ͸Ϋϥογϡ͢Δ

Slide 7

Slide 7 text

ཧ૝

Slide 8

Slide 8 text

ݱ࣮

Slide 9

Slide 9 text

Φεεϝηογϣϯ • App Startup Time: Past, Present, and Future • https://developer.apple.com/videos/play/ wwdc2017/413/ • Optimizing App Startup Time • https://developer.apple.com/videos/play/ wwdc2016/406/

Slide 10

Slide 10 text

dyld 3 • ৽͍͠Dynamic Linker࡞ͬͯΔ • ࣮༻ஈ֊ʹͳͬͨΒϦϯΫ͕ΊͬͪΌૣ͘ͳ ΔΒ͍͠

Slide 11

Slide 11 text

Optimizing Startup Time • ىಈ࣌ؒߴ଎Խͷ஌ݟͷηογϣϯ • ܭଌख๏ͱվળͷํ๏

Slide 12

Slide 12 text

Optimizing Startup Time Lab • ΊͬͪΌχονͳLab͕͔͋ͬͨΒฉ͖ʹ͍ͬ ͨ

Slide 13

Slide 13 text

LabͰฉ͍ͨ͜ͱ

Slide 14

Slide 14 text

Q. Dynamic FrameworkΛ૿ ΍͠·͘ΔͱΊͬͪΌ஗͘ͳͬ ͯࠔͬͯΔΜ͚ͩͲ૿΍͢΂ ͖Ͱ͸ͳ͍ʁ

Slide 15

Slide 15 text

A. ͤ΍ͳ

Slide 16

Slide 16 text

Q. Swiftͷݴޠػೳʹ namespaceͳ͍͠ɺ frameworkΘ͚ͳ͍ͱݫ͍͠ ͱࢥ͏Μ͚ͩͲ

Slide 17

Slide 17 text

A. ΫϥεʹprefixΛ͚ͭ· ͠ΐ͏

Slide 18

Slide 18 text

Q. dyld 3͸iOS 11ͰೖΔͷ ͔ʁ

Slide 19

Slide 19 text

A. ͳʹ΋ݴ͑Δ͜ͱ͸ͳ͍

Slide 20

Slide 20 text

• ۜͷ஄ؙ͸ͳ͍

Slide 21

Slide 21 text

ىಈ࣌ؒͷܭଌํ๏

Slide 22

Slide 22 text

1. InstrumentsΛ࢖͏ • ʮApp Startup Time: Past, Present, and FutureʯͰ঺հ͞ΕͯΔ • Time Profiler • Static Initializer Call(iOS 11)

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

2. Instruments via CLI • ಉ͜͡ͱ͕ίϚϯυϥΠϯ͔Β΋Ͱ͖Δ • instrumentsίϚϯυ • ͨͩ͠ɺग़ྗͨ͠σʔλ͸GUIͰͳ͍ͱӾཡͰ ͖ͳ͍ʢύʔε͢Δํ๏͸ͳ͍ʣ • ৄ͘͠͸man instruments

Slide 25

Slide 25 text

$ instruments -t 'Time Profiler' -w ‘36AF1B72-C261-45BD- AE4A-6593D22F0A' ‘com.yourcompany.InitializeTimeProfiler' Instruments Trace Complete (Duration : 11.811208s; Output : /Users/ giginet/Desktop/InitializeTimeProfiler/instrumentscli1.trace)

Slide 26

Slide 26 text

3. task_info + UI Test • task_infoͰCPU࣌ؒऔͬͯܭଌ͢Δͱྑ͍ͷ Ͱ͸ʁͱݴΘΕͨ • didFinishLaunchingWithOptionsͰͷ࣌ؒΛ औΔ

Slide 27

Slide 27 text

var info = mach_task_basic_info() var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout.size) _ = withUnsafeMutablePointer(to: &info) { infoPointer in return infoPointer.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { (machPoin return task_info( mach_task_self_, task_flavor_t(TASK_BASIC_INFO), task_info_t(machPointer), &count ) } } print(info.system_time) print(info.user_time)

Slide 28

Slide 28 text

4. DYLD_PRINT_STATISTICS • ʮOptimizing App Startup TimeʯͰ঺հ͞Ε ͯΔ • ͦΕͧΕͷ஋ͷҙຯ͸ηογϣϯΛݟΔ͜ͱ

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

Total pre-main time: 307.08 milliseconds (100.0%) dylib loading time: 213.98 milliseconds (69.6%) rebase/binding time: 39.27 milliseconds (12.7%) ObjC setup time: 25.78 milliseconds (8.3%) initializer time: 27.96 milliseconds (9.1%) slowest intializers : libSystem.dylib : 3.17 milliseconds (1.0%) libswiftCoreImage.dylib : 17.56 milliseconds (5.7%)

Slide 31

Slide 31 text

·ͱΊ • ஗͍ͷ͸ݱঢ়Ͳ͏͠Α͏΋ͳ͍ • ΞϓϦͷىಈ࣌ؒܭଌख๏͸ฉ͚ͨ • ࣗಈԽ͍ͨ͠ • Micro Framework Architecture͸ݬ૝ • dyld 3Λ࠲ͯ͠଴͔ͭ͠ແ͍

Slide 32

Slide 32 text

See also • giginet/xcprofiler • https://github.com/giginet/xcprofiler

Slide 33

Slide 33 text

ΦϚέ LabͰੜ͖࢒Δʹ͸

Slide 34

Slide 34 text

ΦϚέɿLabͰੜ͖࢒Δʹ͸ • ୆ຊΛ࡞͍ͬͯ͘ • ʮΏͬ͘Γ஻ͬͯ͘ΕʯͱఝΛࢗ͢ • ಉ͜͡ͱΛ2ਓҎ্ʹฉ͘

Slide 35

Slide 35 text

୆ຊΛ࡞͍ͬͯ͘ • ฉ͘͜ͱΛϦετԽɻจষ΋࡞จ͓ͯ͘͠ • ϝϞΛݟͤͳ͕Β࣭໰͢Δ

Slide 36

Slide 36 text

ʮΏͬ͘Γ஻ͬͯ͘Εʯͱ ఝΛࢗ͢ • ѫࡰͨ͠Β଎߈ʮΏͬ͘Γͯ͘͠ΕཔΉʯ ͱ͔ݴ͓ͬͯ͘ͱେ఍Ώͬ͘Γ஻ͬͯ͘ΕΔ • ࠷ѱɺଧͪࠐΜͰ΋Β͏

Slide 37

Slide 37 text

ಉ͜͡ͱΛ2ਓҎ্ʹฉ͘ • ஌ࣝྔʹ͕ࠩ͋Δ • ଞͷਓʹdelegate͞ΕΔ͜ͱ͕͋Δ • ͱΓ͋͑ͣಉ࣭͡໰Λผʑʹ͓ͯ͘͠ • ҧ͏ճ౴͕ಘΒΕΔ͜ͱ΋͋Δ

Slide 38

Slide 38 text

͝ਗ਼ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠