Optimasi Waktu Bangun - Bagian 1

Hampir setiap pengembang setidaknya sekali mengalami waktu pembangunan yang agak lama untuk proyek mereka. Hal ini menyebabkan berkurangnya produktivitas dan memperlambat proses pengembangan seluruh tim. Seperti yang Anda lihat, meningkatkan waktu pembuatan suatu proyek sangat penting karena memiliki dampak langsung pada waktu aplikasi diterbitkan ke AppStore dan untuk rilis lebih cepat fitur-fitur baru dari aplikasi Anda.

Pada artikel ini, kita akan belajar cara membuat profil suatu rakitan dalam Xcode dan mendapatkan metrik. Pada artikel selanjutnya saya akan berbicara tentang metode untuk menghilangkan kemacetan dan mempercepat perakitan proyek. Juga harus disebutkan bahwa kita akan menggunakan proyek iOS Kickstarter, yang dapat ditemukan di Github . Jadi mari kita mulai!

Apa yang kita ukur?


Hal pertama yang harus kita lakukan adalah menentukan apa yang ingin kita ukur dan optimalkan. Dua opsi dapat dipertimbangkan:

  • Clean build - clean and build the project. Seringkali, pembersihan dibangun di CI untuk memeriksa permintaan tarik baru dan menjalankan tes unit.
  • Membangun tambahan - membangun proyek setelah perubahan signifikan pada kode sumber. Perakitan ini dibuat oleh pengembang sambil mengerjakan fungsionalitas baru.

Dalam sebagian besar kasus, mengurangi waktu selama Clean build juga harus mempercepat build Incremental . Opsi terbaik adalah membuat metrik untuk kedua jenis rakitan dan melacaknya. Kami akan mengukur waktu pembuatan menggunakan konfigurasi Debug hanya karena digunakan sebagian besar waktu dan memiliki dampak yang lebih besar pada pengembangan.

Kami menghitung waktu perakitan


Cara paling efektif untuk meningkatkan waktu pembuatan harus berupa pendekatan berdasarkan penerapan dan verifikasi perubahan berdasarkan metrik tertentu. Pertimbangkan mereka, serta alat yang dapat kita gunakan untuk memperoleh informasi tentang waktu pembangunan proyek.

Laporan waktu pembuatan Xcode


Kita dapat dengan mudah mendapatkan data waktu pembuatan menggunakan Xcode. Ini melacak semua build secara default dan memungkinkan Anda untuk melihat waktu build proyek di navigator laporan.

gambar

Anda juga memiliki opsi untuk menampilkan informasi serupa di Xcode di panel penampil aktivitas . Itu dapat diaktifkan untuk tampilan menggunakan baris perintah dengan menjalankan perintah: Waktu pembangunan proyek ditampilkan setelah perakitan bersama dengan pesan "Berhasil". Ini hanya dua opsi dasar yang akan memberi Anda gambaran kasar tentang waktu build Clean and Incremental .

defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES



gambar



Ringkasan waktu pembuatan proyek dalam Xcode


Ringkasan Waktu Pembuatan Xcode - Teman pertama Anda yang mendapatkan statistik waktu dan hambatan. Anda dapat menjalankannya melalui Product-> Perform Action-> Build With Timing Summary . Sekarang Anda akan melihat perincian besar waktu yang dihabiskan untuk berbagai tugas:

gambar

Metode ini harus menjadi titik awal yang baik untuk menemukan tugas yang paling memakan waktu dalam proses perakitan. Tangkapan layar di atas menunjukkan bahwa CompileStoryboard , CompileXIB , CompileSwiftSources, dan fase PhaseScriptExecution mengambil sebagian besar waktu pembuatan. Xcode mampu menyelesaikan sebagian tugas secara paralel, sehingga perakitan diselesaikan jauh lebih cepat daripada waktu yang diperlukan untuk menyelesaikan tugas dari masing-masing perintah.

Kita bisa mendapatkan ringkasan waktu build untuk Clean build menggunakan xcodebuild dengan opsi - buildWithTimingSummary : Sekarang mari kita mendapatkan metrik yang mirip dengan build Incremental. Perlu dicatat bahwa waktu build inkremental sepenuhnya tergantung pada file yang sedang dimodifikasi dalam proyek. Untuk mendapatkan hasil yang konsisten, Anda dapat memodifikasi satu file dan mengkompilasi proyek. Tidak seperti sistem Buck atau Bazel, Xcode menggunakan cap waktu untuk menentukan apa yang telah berubah dan apa yang perlu dibangun kembali. Kami dapat memperbarui cap waktu menggunakan sentuhan:

xcodebuild -project 'Kickstarter.xcodeproj' \
-scheme 'Kickstarter-iOS' \
-configuration 'Debug' \
-sdk 'iphonesimulator' \
-showBuildTimingSummary \
clean build | sed -n -e '/Build Timing Summary/,$p'

Build Timing Summary
CompileStoryboard (29 tasks) | 87.128 seconds
CompileSwiftSources (4 tasks) | 54.144 seconds
PhaseScriptExecution (14 tasks) | 18.167 seconds
CompileAssetCatalog (2 tasks) | 6.532 seconds
CompileXIB (21 tasks) | 6.293 seconds
CodeSign (7 tasks) | 3.069 seconds
Ld (4 tasks) | 2.342 seconds
LinkStoryboards (2 tasks) | 0.172 seconds
CompileC (3 tasks) | 0.122 seconds
Ditto (20 tasks) | 0.076 seconds
Touch (4 tasks) | 0.007 seconds
** BUILD SUCCEEDED ** [92.620 sec]



touch KsApi/mutations/CancelBackingMutation.swift && \
xcodebuild -project 'Kickstarter.xcodeproj' \
-scheme 'Kickstarter-iOS' \
-configuration 'Debug' \
-sdk 'iphonesimulator' \
-showBuildTimingSummary \
build | sed -n -e '/Build Timing Summary/,$p'

Build Timing Summary
PhaseScriptExecution (14 tasks) | 18.089 seconds
CodeSign (7 tasks) | 2.990 seconds
CompileSwiftSources (1 task) | 1.245 seconds
Ld (1 task) | 0.361 seconds
** BUILD SUCCEEDED ** [23.927 sec]

Ketik Verifikasi Peringatan


Ketika waktu kompilasi menjadi hambatan, kita bisa mendapatkan informasi lebih lanjut dengan mengatur Bendera Swift Lain ke opsi pembangunan proyek dalam Xcode. Ketika flag diaktifkan, Xcode menghasilkan peringatan untuk fungsi atau ekspresi apa pun yang membutuhkan lebih dari 100 ms untuk menentukan tipe variabel:

  • -Xfrontend -warn-long-function-bodies = 100
  • -Xfrontend -warn-long-expression-type-checking = 100

gambar

Sekarang Anda tahu kode di mana kompiler Swift mengalami masalah dan sekarang Anda dapat mencoba memperbaikinya.

Opsi Diagnostik Kompiler


Kompiler Swift memiliki banyak opsi diagnostik bawaan yang dapat Anda gunakan untuk membuat profil perakitan.

  • -driver-time-compilation - tingkat sinkronisasi tugas yang dilakukan oleh pengemudi.
  • -Xfrontend -debug-time-compilation — .
  • -Xfrontend -debug-time-function-bodies – .
  • -Xfrontend -debug-time-expression-type-checking – .

Mari kita gunakan kotak centang -debug-time-compilation untuk mendapatkan informasi tentang file paling lambat saat kompilasi: Seperti yang Anda lihat, butuh 25 detik untuk mengkompilasi SettingsNewslettersCellViewModel.swift . Dari log perakitan, Anda bisa mendapatkan informasi tambahan tentang waktu kompilasi file: Sekarang jelas bahwa Pengecekan tipe dan analisis Semantic adalah pekerjaan yang paling memakan waktu. Mari kita lanjutkan dan daftar fungsi dan ekspresi paling lambat pada langkah Memeriksa Jenis :

xcodebuild -project 'Kickstarter.xcodeproj' \
-scheme 'Kickstarter-iOS' \
-configuration 'Debug' \
-sdk 'iphonesimulator' \
clean build \
OTHER_SWIFT_FLAGS="-Xfrontend -debug-time-compilation" |
awk '/CompileSwift normal/,/Swift compilation/{print; getline; print; getline; print}' |
grep -Eo "^CompileSwift.+\.swift|\d+\.\d+ seconds" |
sed -e 'N;s/\(.*\)\n\(.*\)/\2 \1/' |
sed -e "s|CompileSwift normal x86_64 $(pwd)/||" |
sort -rn |
head -3

25.6026 seconds Library/ViewModels/SettingsNewslettersCellViewModel.swift
24.4429 seconds Library/ViewModels/PledgeSummaryViewModel.swift
24.4312 seconds Library/ViewModels/PaymentMethodsViewModel.swift



===-------------------------------------------------------------------------===
Swift compilation
===-------------------------------------------------------------------------===
Total Execution Time: 25.6026 seconds (26.6593 wall clock)

---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Name ---
24.4632 ( 98.3%) 0.5406 ( 76.5%) 25.0037 ( 97.7%) 26.0001 ( 97.5%) Type checking and Semantic analysis
0.0981 ( 0.4%) 0.1383 ( 19.6%) 0.2364 ( 0.9%) 0.2872 ( 1.1%) Name binding
0.1788 ( 0.7%) 0.0043 ( 0.6%) 0.1831 ( 0.7%) 0.1839 ( 0.7%) IRGen
0.0508 ( 0.2%) 0.0049 ( 0.7%) 0.0557 ( 0.2%) 0.0641 ( 0.2%) Parsing
0.0599 ( 0.2%) 0.0020 ( 0.3%) 0.0619 ( 0.2%) 0.0620 ( 0.2%) SILGen
0.0285 ( 0.1%) 0.0148 ( 2.1%) 0.0433 ( 0.2%) 0.0435 ( 0.2%) SIL optimization
0.0146 ( 0.1%) 0.0015 ( 0.2%) 0.0161 ( 0.1%) 0.0162 ( 0.1%) Serialization, swiftmodule
0.0016 ( 0.0%) 0.0006 ( 0.1%) 0.0022 ( 0.0%) 0.0022 ( 0.0%) Serialization, swiftdoc
0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0001 ( 0.0%) SIL verification, pre-optimization
0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0000 ( 0.0%) AST verification
0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0000 ( 0.0%) 0.0000 ( 0.0%) SIL verification, post-optimization
24.8956 (100.0%) 0.7069 (100.0%) 25.6026 (100.0%) 26.6593 (100.0%) Total



xcodebuild -project 'Kickstarter.xcodeproj' \
-scheme 'Kickstarter-iOS' \
-configuration 'Debug' \
-sdk 'iphonesimulator' \
clean build \
OTHER_SWIFT_FLAGS="-Xfrontend -debug-time-expression-type-checking \
-Xfrontend -debug-time-function-bodies" |
grep -o "^\d*.\d*ms\t[^$]*$" |
awk '!visited[$0]++' |
sed -e "s|$(pwd)/||" |
sort -rn |
head -5

16226.04ms Library/Styles/UpdateDraftStyles.swift:31:3
10551.24ms Kickstarter-iOS/Views/RewardCardContainerView.swift:171:16 instance method configureBaseGradientView()
10547.41ms Kickstarter-iOS/Views/RewardCardContainerView.swift:172:7
8639.30ms Kickstarter-iOS/Views/Controllers/AddNewCardViewController.swift:396:67
8233.27ms KsApi/models/templates/ProjectTemplates.swift:94:5

Dengan cara yang sama, kami membuat profil perakitan kami dan menemukan bahwa pada tahap pengecekan tipe ada hambatan. Sebagai langkah berikutnya, Anda dapat melihat fungsi dan ekspresi yang tercantum di atas dan mencoba untuk mengoptimalkan inferensi tipe .

Target Build Time


Dianjurkan untuk mengukur waktu rakitan target secara terpisah dan menampilkannya pada grafik. Anda dapat membantu memahami target mana yang sedang dikumpulkan atau dapat dikumpulkan secara paralel. Untuk melakukan ini, Anda dapat menggunakan alat rendering xcode-build-time. Mari kita atur sebagai RubyGem: Setelah instalasi selesai, jalankan perintah berikut untuk memasukkan log timestamp di Fase Run Script Build dari target Anda: Kemudian kompilasi proyek dan laporkan menggunakan: Sebagai hasilnya, Anda harus mendapatkan bagan Gantt yang bagus dengan waktu pembuatan yang menunjukkan waktu. majelis semua target Anda:

gem install xcode-build-times



xcode-build-times install



xcode-build-times generate



gambar

Metrik Teragregasi


Akan luar biasa untuk menggabungkan berbagai indikator yang disebutkan di atas. XCLogParser adalah alat yang hebat yang dapat membantu Anda dengan ini. Ini adalah penganalisis log untuk xcactivitylog yang dihasilkan oleh Xcode, dan memberikan banyak informasi tentang waktu pembuatan untuk setiap modul dan file dalam proyek, peringatan, kesalahan, dan hasil pengujian unit. Anda dapat menginstalnya dengan mengkloning repositori dan meluncurkan melalui baris perintah: Ini adalah laporan yang dibuat untuk proyek iOS Kickstarter:

git clone https://github.com/spotify/XCLogParser
rake build
xclogparser parse --project Kickstarter --reporter html



gambar

Otomatisasi


Perlu dicatat bahwa metrik waktu perakitan tergantung pada perangkat keras dan penggunaannya. Anda dapat menggunakan peralatan Anda untuk eksperimen. Pilihan terbaik adalah mengotomatiskan proses sebanyak mungkin dan menggunakan peralatan CI khusus untuk metrik harian. Pada akhirnya, mereka dapat dipantau di dashboard dan diberi tahu akan semakin buruknya waktu menggunakan Slack.

Kesimpulan


Mengurangi waktu pembangunan proyek sangat penting untuk meningkatkan produktivitas pengembang. Hari ini kami belajar bagaimana mengukur waktu pembuatan suatu proyek dan mendapatkan beberapa metrik untuk dianalisis ...

Dalam publikasi berikutnya, kami akan mempertimbangkan metode yang dapat digunakan untuk mengurangi waktu pembuatan.

Terima kasih sudah membaca!

All Articles