iOS和macOS性能最佳化

iOS和macOS性能最佳化

《iOS和macOS性能最佳化:Cocoa、Cocoa Touch、Objective-C和Swift》 從CPU、記憶體、Swift、I/O、圖像和UI入手全方位提升蘋果系統性能,幫你寫出高性能代碼實現 【德】Marcel Weiher 著 李俊陽 等 譯 ISBN 978-7-121-33814-4 2018年7月出版 定價:99.00元 368頁 16開

編輯推薦

√從基本原理出發,了解蘋果設備性能的常見陷阱和誤解,解決蘋果系統性能問題;

√理解最最佳化原則、測量、工具、陷阱和技巧;

√了解什麼時候要仔細最佳化,什麼時候不值得花時間最佳化;

√平衡性能和封裝,創建高效的對象表示、通信、數據訪問和計算;

√避免拖慢Objective-C程式和阻礙後續最佳化的錯誤;

√修復記憶體和資源管理中的漏洞和其他問題;

√解決與驅動器、網路、序列化和SQLite相關的I/O問題;

√了解代碼繪圖和不會對有限的iOS設備資源造成太大負擔的用戶界面;

√所有開發人員都需要了解的關於Swift的性能信息。

內容提要

隨著套用功能的日益增加,性能問題也逐漸浮出水面,進入我們的視野之中。《iOS和macOS性能最佳化:Cocoa、Cocoa Touch、Objective-C和Swift》作者Marcel Weiher在性能調優領域有著豐富的經驗,在他的帶領下,你將會了解如何提升CPU、記憶體、I/O、圖像、Swift等方面的性能,如何在開發過程中定位到性能的瓶頸和問題,他同時還介紹了性能最佳化的編程技巧和最佳實踐,從而幫助你寫出更高效、更快速的代碼。此外,你還將學習到定位性能問題的工具使用方法以及最佳實踐,並跟隨示例來學習性能最佳化。

《iOS和macOS性能最佳化:Cocoa、Cocoa Touch、Objective-C和Swift》適合尋求進階及所有對性能最佳化感興趣的iOS 開發人員閱讀。

目錄

1 CPU:原理 1

一個簡單的例子 2

(微)基準的危險 3

更多整數求和的方式 4

Swift 5

其他語言 7

混編的力量 9

趨勢 10

操作成本 12

複雜度計算 14

總結 16

2 CPU:測量和工具 17

命令行工具 18

top 18

time 19

sample 19

Xcode 測量工具 22

Instruments 23

設定和數據收集 24

性能分析選項 25

基本分析 27

原始碼 29

數據挖掘I:Focus 31

數據挖掘II:Pruning 34

內部測量 35

測試 36

dtrace(dynamic tracing,動態跟蹤) 37

職責之外的最佳化 38

總結 39

3 CPU:陷阱和最佳化技巧 41

數據表示 41

基本類型 42

字元串 45

對象 47

存取器 48

公共訪問(Public Access) 51

對象創建和快取 52

可變性和快取 53

惰性求值 55

快取注意事項 55

陷阱:通用(中級)表示 57

數組和批處理 58

字典 60

訊息傳遞 63

IMP 快取 65

轉發 67

均勻性和最佳化 69

方法 70

陷阱:CoreFoundation 70

多核 71

執行緒(Thread) 72

工作佇列 73

有節制地最佳化 74

4 CPU 實戰:XML 解析 77

HTML 掃描器 78

將回調映射為訊息 81

對象 83

對象的高效性能 85

性能評估 88

調整 91

最佳化整個組件:MAX 92

MAX 實現 94

總結 95

5 記憶體:原理 97

記憶體層次結構 97

Mach 虛擬記憶體 103

堆和棧 104

棧分配 106

使用malloc()進行堆分配 108

資源管理 111

垃圾回收 111

Foundation 對象所有權 112

跟蹤垃圾回收 113

自動引用計數(Automatic Reference Counting) 114

過程式資源回收 115

總結 115

6 記憶體:測量與工具 117

Xcode 計量表 117

命令行工具 118

top 118

heap 120

leaks 及malloc_debug 122

代碼內進行記憶體測量 123

記憶體監測工具 124

Leaks 124

Allocations 125

VM Tracker 132

計數器與性能監測事件 133

總結 134

7 記憶體:陷阱和最佳化技巧 137

引用計數 137

避免記憶體泄漏 139

Foundation 對象和基本類型對比 141

更小的結構 143

千禧危機 145

壓縮 145

可清除記憶體 146

記憶體與並發 146

架構注意事項 147

臨時分配與對象快取 152

NSCache 與libcache 153

記憶體映射檔案 154

madvise 157

iOS 注意事項 158

ARC 最佳化 158

總結 161

8 記憶體管理實戰:FilterStream 架構 163

UNIX 管道及過濾器 163

面向對象的過濾器 165

DescriptionStream 166

消除description 中的無限遞歸 170

數據流層次結構 172

總結 173

9 Swift 175

Apple 所聲稱的Swift 性能 175

語言特性 177

基準代碼 179

Swift 性能評估 180

基本性能特徵 180

集合 181

更進一步 190

Nginx HTTP 解析器 190

Freddy JSON 解析器 191

圖片處理 191

觀察 192

編譯時間 193

類型推斷 193

泛型特化 195

全模組最佳化 197

控制編譯時間 197

面向最佳化器編程 198

一個足夠智慧型的編譯器 199

最佳化編譯器之死 201

實用建議 203

備用方案 204

總結 207

10 I/O:原理 209

硬體 209

硬碟驅動器 209

固態硬碟 211

網路 212

作業系統 212

抽象概念:位元組流 212

檔案I/O 214

網路棧 218

總結 218

11 I/O:測量與工具 221

負形空間:top 與time 222

信息概覽:iostat 和netstat 223

Instruments 224

詳細追蹤:fs_usage 228

總結 231

12 I/O:陷阱和最佳化技巧 233

將位元組封裝為NSData 233

記憶體映射異常 235

如何分塊 237

UNIXy I/O 238

網路I/O 240

堆疊傳輸 241

限制請求 243

數據處理 244

異步I/O 245

HTTP 服務 246

序列化 250

記憶體轉儲 251

一個簡單的XML 格式 252

屬性列表 254

歸檔 256

序列化總結 258

CoreData 260

批量創建和更新 261

Fetch 和Fault 技術 263

對象互動 266

子集 266

分析 267

SQLite 267

關係型和其他非資料庫 269

事件發布 270

混合形式 271

隔離存儲 272

總結 272

13 I/O:實戰 273

iPhone 遊戲字典 273

有趣的屬性列表 277

二進制屬性列表讀取器 278

懶載入 282

避免中間代碼 284

逗號分隔值 287

公共運輸調度數據 289

站點信息 290

站點停靠時間檢索 291

站點停靠時間導入 292

更快的CSV 解析 294

對象分配 294

Push 與Pull 的比較 296

感興趣的鍵 296

並行 296

總結 299

14 圖像和UI:原理 301

回響能力 301

軟體和API 302

Quartz 和PostScript 圖像模型 305

OpenGL 307

Metal 307

圖形硬體加速 307

從Quartz 到Core Animation 311

總結 314

15 圖像和UI:測量和工具 315

CPU 分析儀 315

Quartz 調試 317

Core Animation 工具 318

當CPU 不再是問題 319

我在測量什麼 327

總結 329

16 圖像和UI:陷阱和最佳化技巧 331

陷阱 331

最佳化技巧 332

過多通信導致安裝緩慢 333

節流顯示 333

使用節流顯示 335

今日安裝程式和進度報告 335

iPhone 無法承受之重 336

一切都是假象 338

圖像的縮放和剪下 338

縮略圖繪製 340

如何確定沒有繪製縮略圖 341

如何真的不繪製縮略圖 341

如何繪製非縮略圖 342

在iPhone 上繪製直線 344

總結 346

17 圖像和UI:實戰 347

優美的天氣套用 347

更新 348

探索PNG 348

頭腦風暴 350

JPEG 數據點 350

測量時的小錯誤 351

JPNG 與JPJP 353

優美的啟動 353

Wunderlist 3 354

Wunderlist 2 354

整體架構 355

URI 與進程中REST 356

最終一致的異步數據存儲 357

RESTOperation 佇列 358

流暢、反應靈敏的UI 359

簡評Wunderlist 361

總結 361

作者簡介

Marcel Weiher 是一名軟體工程師和研究人員,擁有超過25 年的Cocoa 相關技術經驗。Marcel 致力於性能最佳化相關的工作,曾在英國廣播公司最佳化過世界上極繁忙的網路的性能,解決了當下機器上難以忍受的積壓問題,而其在Apple 的Mac OS X 性能團隊任職時,也幫助過其他工程師提高代碼性能。

除了幫助知名公司和初創企業開發屢獲殊榮的軟體以及組建開發團隊,Marcel 還教授課程,維護部落格,出席會議演講,為開源項目做貢獻,並發明了如高階訊息傳遞等新技術。自1987 年開始,Marcel 著手Objective-C 的實現,開始從事與程式語言相關的工作,最終實現了Objective-Smalltalk 架構研究語言。Marcel 目前在柏林的微軟公司擔任首席軟體工程師,並擁有自己的軟體和諮詢公司metaobject ltd。

譯者序

我們在開發套用的時候,最關心的都是些什麼呢?首要的自然就是功能需求了,此外還有那些炫酷的用戶界面和轉場動畫。當我們進入書店,或者在網上搜尋時,映入眼帘的普遍都是開發入門、功能需求、動畫特效等諸如此類的書籍和文章。那么,我們何時才會關注那些所謂的“非功能性需求”呢?

在我們翻譯的上一本書《iOS 套用安全權威指南》中,我們很高興地看到了iOS 開發中關於“安全性”需求的話題。在本書中,我們將繼續關注“性能和可靠性”這一非功能性需求。

提到性能,我們通常想到的是後台的伺服器性能和網路頻寬。在出現性能問題的時候,我們會想方設法地提升後台伺服器的性能,增加CPU 核心、增加記憶體、增加網路頻寬……但是有沒有想過,有時候套用本身的性能也會阻礙用戶數量的增長,甚至嚴重影響用戶體驗。試想,如果用戶在使用套用的時候,出現了嚴重的卡頓,這種情況對於用戶而言往往是無法忍受的。這對很多公司而言,致命性不言而喻。更嚴重的是,套用一旦出現了性能問題,我們是沒辦法通過增加CPU 核心、記憶體等方法來進行提升的。因此,我們需要對套用進行性能調優。

但是,目前市面上關於iOS 性能最佳化的文章和書籍實在是少之又少,我們通常會看到人們用Instruments 的Allocations、Leaks 等工具來檢查性能問題,但是它們的具體用法是怎么樣的呢?我們要怎樣做才能找到套用真實的性能瓶頸呢?有哪些問題是通過編寫代碼本身就可以規避的呢?這些,本書都能夠告訴你。

我們相信,每位軟體開發者都有一種精益求精、追求卓越的心態和想法,在我們完成了龐雜的功能需求之後,自然就會開始關注如何提升用戶體驗,其中就包括性能最佳化。

無論你的套用規模如何,我們都強烈建議大家閱讀本書,掌握一些基本的技巧,只要在開發過程中規避這些陷阱和漏洞,那么基本上我們的套用就能夠滿足性能的要求,在絕多數時間,使你完全沒必要擔憂性能的相關問題。

我們都知道,Xcode 擁有一個簡單的性能檢測視窗Debug Navigator,其中分別展示了CPU、記憶體、硬碟、網路的使用量等。類似地,本書包含如下四部分內容:CPU、記憶體、I/O,以及圖像處理和回響速度。每部分內容都同時包括了基本的理論知識、測量的工具和度量標準、常見的問題和處理方法,以及真實的案例演示。內容循序漸進,由淺至深,無論你是急於尋找性能問題的解決方案,還是想要系統化地學習性能調優的相關知識,都能夠依據這個完整的架構體系尋找到想要的內容。

在本書翻譯過程中,由於書中的內容對於我們而言也比較新穎,在百忙之餘,我們也一一根據書中的案例和步驟先行學習、試驗和體會,以期能夠用更為準確的語言和文字,將書中的思想完整地分享給各位讀者朋友。在此也特別感謝參與校對的SwiftGG 翻譯組的小夥伴們,對我們在翻譯過程中出現的錯誤進行了勘正。同時也感謝電子工業出版社的編輯、審稿專家,他們認真負責、高效細心地進行了編輯和校對,也給我們提出了不少好的建議。當然,由於本書用到了大量的專業術語,在中文世界中找不到相應的描述,因此我們也斗膽“創造”了很多新詞,如果出現了缺漏、不準確、不到位的情況,還請各位讀者批評指正。

最後,再次感謝你關注這本講解性能最佳化的書籍,我們相信你一定能從這本書中學習到各種有用的知識,向進階的iOS 開發者更進一步!

李俊陽

2018 年3 月3 日

前言

性能是軟體極其重要的特性之一。若沒有世界一流的性能,軟體也就稱不上是世界級的。長期以來,硬體的改善意味著擔心軟體的性能似乎是浪費時間的,但隨著摩爾定律不再自然而然地提供顯著的自動性能改進,性能最佳化也逐步回到了計算機科學和工程的前沿。

此外,儘管底層硬體的性能已經提升了很多倍,但終端用戶對性能提升的感知似乎並不明顯。比爾·蓋茨認為“軟體的速度每18 個月就會變慢一半”,同樣在A Plea for LeanSoftware(《為軟體瘦身請命》)一文中提出的維爾特定律還認為,“軟體變慢的速度永遠快過硬體變快的速度”1。

iPad 面世之初,行業資深人士被其流體式的布局界面所驚艷,但同時不得不接受一個只配備了1GHz 的CPU,這是讓人感到遺憾的一點。不過,那時的iPad 比我的Apple II快了1000 多倍,比大屏的NeXT Cube 也要快40 倍。如果真的有什麼值得詫異的,那就是在使用GPU 處理螢幕渲染的時候,它居然沒怎么變快。

本書將嘗試在Objective-C、Cocoa 和Cocoa Touch 的背景下深入了解這些發展的根本原因,並嘗試提供技術,幫助我們充分利用計算機驚人的原始力量——那些易於肆意揮霍的力量。我會試圖告知何時揮霍計算機的性能是恰當的,以及何時需要對性能引起高度重視。程式設計師的注意力也是一種稀缺資源,但卻經常浪費在嘗試最佳化無關緊要的部分程式上。

主題將涵蓋延遲與頻寬,處理事項成本損耗(開銷)與實際完成工作的對比,其具有普遍性,且硬體和軟體棧的表現形式隨級別不同而不同。

你可能注意到任何單一的操作時間取決於機器的速度,而機器總是足夠快的,因此得出關鍵方程項目數損耗。大多數最佳化是減少公式的一部分或兩部分,通常我們要先嘗試將其分解。

降低成本損耗的一種常用方法:認識到損耗實際上是由損耗1 和損耗2 兩個獨立的成本組成的,並且兩者之中有且僅有一個需要套用於所有項目——項目數×(損耗1+損耗2)→損耗1+項目數×損耗2。我稱之為基本最佳化方程,大部分最佳化技術均屬於這一類,它也是構成我們每天處理的大多數硬體/軟體棧的基礎。

本書有一個非常規則的目錄結構,將依次討論性能的4 個基本主題領域:

1.CPU 的性能

2.記憶體

3.I/O

4.圖像和回響速度

儘管已經努力保證每個主題領域的獨立性,但是邏輯之間千絲萬縷,因此對基礎的主題有一定了解有助於對後續主題的理解。

上述4 個主題分別又被劃分成4 個特定的興趣領域,如下。

1.原理。

2.測量和工具。

3.陷阱和最佳化技巧。

4.實戰演示套用技術。

再次強調,我們將遵循這樣一個邏輯結構:在進行實際的性能最佳化技術之前,你需要了解一些理論知識並知道如何測量,同樣地,如果基本熟悉前面幾個話題,應該也能夠深入感興趣的特定領域。

本書採用這種結構劃分成了44 =16 章,加上記憶體和I/O 之間穿插的特別章節Swift,總計17 章。Swift 在整本書中被廣泛使用,其獨特的性能特點值得我們新開一章來討論。

對我而言,軟體性能是一種激情和呼喚,貫穿了我的整個職業生涯。關於性能,我深有體會,性能無法自動最佳化,我們也無法在最後時刻棄它而去。另一方面,不要過分擔心性能,才能集中精力在真正需要的性能工作上。這並非自相矛盾,設定一個合理的基礎性能水平,通常情況下軟體都是能夠達到的,這樣就免去了大部分時間都在對性能擔憂的困擾。

簡而言之,本書是關於如何出色完美地提升軟體執行效率的一本書。  

相關詞條

熱門詞條

聯絡我們