Python非常適用于快速開發(fā)、生產(chǎn)環(huán)境部署和可擴(kuò)展的系統(tǒng)。本書包含了讀者在日常工作會(huì)遇到的多數(shù)性能問題及其解決方案。本書共有12章,圍繞如何進(jìn)行代碼優(yōu)化和加快實(shí)際應(yīng)用的運(yùn)行速度進(jìn)行講解。本書還介紹了如何解決CPU密集型問題、數(shù)據(jù)傳輸和內(nèi)存密集型問題,如何通過移動(dòng)數(shù)據(jù)、使用PyPy即時(shí)編譯器和異步I/O提升性能。本書主要包括以下內(nèi)容:計(jì)算機(jī)原理、列表和元組、字典和集合、迭代器、Python模塊、并發(fā)性、集群計(jì)算等。最后,本書通過一系列真實(shí)案例展現(xiàn)了在應(yīng)用場(chǎng)景中使用Python時(shí)需要注意的問題。
前言
第 1章 理解高性能Python 1
1.1 基本的計(jì)算機(jī)系統(tǒng) 1
1.1.1 計(jì)算單元 2
1.1.2 存儲(chǔ)單元 4
1.1.3 通信層 6
1.2 綜合考慮 8
1.3 為何使用Python 11
1.4 如何成為高性能程序員 13
1.4.1 最佳實(shí)踐 14
1.4.2 對(duì)Notebook最佳實(shí)踐的思考 15
1.4.3 重新發(fā)現(xiàn)工作的樂趣 16
第 2章 通過剖析找出瓶頸 17
2.1 高效地剖析 18
2.2 朱利亞集合簡(jiǎn)介 19
2.3 計(jì)算整個(gè)朱利亞集合 22
2.4 簡(jiǎn)單計(jì)時(shí)方法—print語(yǔ)句和裝飾器 25
2.5 使用UNIX命令time的簡(jiǎn)單計(jì)時(shí) 27
2.6 使用模塊cProfile 29
2.7 使用SnakeViz可視化cProfile的輸出 34
2.8 使用line_profiler逐行剖析 35
2.9 使用memory_profiler診斷內(nèi)存占用情況 40
2.10 使用PySpy查看既有進(jìn)程 47
2.11 字節(jié)碼:幕后發(fā)生的情況 48
2.11.1 使用模塊dis查看CPython字節(jié)碼 48
2.11.2 復(fù)雜度隨方法而異 50
2.12 優(yōu)化期間使用單元測(cè)試確保代碼正確 52
2.13 確保代碼剖析成功的策略 55
2.14 小結(jié) 56
第3章 列表和元組 57
3.1 更高效的查找方式 60
3.2 比較列表和元組 62
3.2.1 作為動(dòng)態(tài)數(shù)組的列表 63
3.2.2 作為靜態(tài)數(shù)組的元組 66
3.3 小結(jié) 67
第4章 字典和集合 69
4.1 字典和集合的工作原理 72
4.1.1 插入和檢索 72
4.1.2 刪除 76
4.1.3 調(diào)整長(zhǎng)度 76
4.1.4 散列函數(shù)和熵 76
4.2 字典和名稱空間 80
4.3 小結(jié) 83
第5章 迭代器和生成器 84
5.1 無窮數(shù)列迭代器 88
5.2 延遲執(zhí)行生成器 89
5.3 小結(jié) 93
第6章 矩陣和向量計(jì)算 94
6.1 問題簡(jiǎn)介 95
6.2 Python列表不夠好嗎 99
6.3 內(nèi)存碎片 104
6.3.1 理解perf 106
6.3.2 根據(jù)perf的輸出做決策 108
6.3.3 進(jìn)入numpy 108
6.4 使用numpy解決擴(kuò)散問題 111
6.4.1 內(nèi)存分配和就地操作 114
6.4.2 有選擇地優(yōu)化:找出需要修復(fù)的地方 118
6.5 numexpr:讓你能夠更快、更輕松地執(zhí)行就地操作 121
6.6 警示故事:對(duì)優(yōu)化進(jìn)行驗(yàn)證(scipy) 122
6.7 從矩陣優(yōu)化獲得的經(jīng)驗(yàn)教訓(xùn) 124
6.8 Pandas 126
6.8.1 Pandas的內(nèi)部模型 127
6.8.2 將函數(shù)應(yīng)用于多行數(shù)據(jù) 128
6.8.3 根據(jù)部分結(jié)果而不是使用拼接來創(chuàng)建DataFrame和Series 135
6.8.4 有多種解決問題的方式(而且可能有更快的方式) 136
6.8.5 Pandas高效開發(fā)建議 137
6.9 小結(jié) 138
第7章 編譯成C代碼 139
7.1 速度提升方法 140
7.2 JIT編譯器和AOT編譯器 141
7.3 為何類型信息有助于提高代碼運(yùn)行速度 142
7.4 使用C語(yǔ)言編譯器 143
7.5 回顧朱利亞集合示例 143
7.6 Cython 144
7.7 pyximport 146
7.7.1 使用Cython標(biāo)注選項(xiàng)來分析代碼塊 146
7.7.2 添加類型標(biāo)注 149
7.8 Cython和numpy 152
7.9 Numba 156
7.10 PyPy 159
7.10.1 垃圾收集方面的差異 160
7.10.2 運(yùn)行PyPy及安裝模塊 160
7.11 速度提升小結(jié) 162
7.12 各種技術(shù)的適用場(chǎng)景 163
7.13 圖形處理單元 165
7.13.1 動(dòng)態(tài)圖:PyTorch 165
7.13.2 GPU基本剖析 168
7.13.3 GPU性能考慮因素 169
7.13.4 在什么情況下使用GPU 170
7.14 語(yǔ)言交互接口 172
7.14.1 ctypes 173
7.14.2 cffi 175
7.14.3 f2py 177
7.14.4 CPython模塊 180
7.15 小結(jié) 184
第8章 異步I/O 186
8.1 異步編程簡(jiǎn)介 187
8.2 async/await的工作原理 190
8.2.1 串行爬蟲 191
8.2.2 gevent 192
8.2.3 tornado 196
8.2.4 aiohttp 199
8.3 兼具CPU密集型和I/O密集型的問題 202
8.3.1 串行版 203
8.3.2 分批處理結(jié)果 204
8.3.3 完全異步 207
8.4 小結(jié) 211
第9章 模塊multiprocessing 213
9.1 模塊multiprocessing概述 216
9.2 使用蒙特卡羅方法估算圓周率 217
9.3 使用進(jìn)程和線程估算圓周率 219
9.3.1 使用Python對(duì)象 219
9.3.2 使用Joblib而不是multiprocessing 225
9.3.3 并行系統(tǒng)中的隨機(jī)數(shù) 229
9.3.4 使用numpy 230
9.4 查找素?cái)?shù) 232
9.5 使用進(jìn)程間通信驗(yàn)證素?cái)?shù) 242
9.5.1 串行解決方案 247
9.5.2 樸素進(jìn)程池解決方案 247
9.5.3 改進(jìn)的樸素進(jìn)程池解決方案 248
9.5.4 將Manager.Value用作標(biāo)志 249
9.5.5 將Redis用作標(biāo)志 251
9.5.6 將RawValue用作標(biāo)志 253
9.5.7 將mmap用作標(biāo)志 254
9.5.8 將mmap用作標(biāo)志(終極版) 255
9.6 使用multiprocessing共享numpy數(shù)據(jù) 257
9.7 同步文件和變量訪問 263
9.7.1 鎖定文件 263
9.7.2 鎖定值 267
9.8 小結(jié) 269
第 10章 集群和作業(yè)隊(duì)列 271
10.1 集群的優(yōu)點(diǎn) 272
10.2 集群的缺點(diǎn) 273
10.2.1 糟糕的集群升級(jí)策略讓華爾街大牛損失4.62億美元 274
10.2.2 Skype全球24小時(shí)中斷服務(wù) 274
10.3 常見的集群設(shè)計(jì) 275
10.4 如何啟動(dòng)集群解決方案 276
10.5 使用集群時(shí)如何避免麻煩 276
10.6 兩種集群解決方案 277
10.6.1 使用IPython Parallel為研究工作提供支持 278
10.6.2 使用Dask并行化Pandas 281
10.7 使用NSQ打造健壯的生產(chǎn)集群 284
10.7.1 隊(duì)列 284
10.7.2 發(fā)布者/訂閱者 285
10.7.3 分布式素?cái)?shù)計(jì)算 287
10.8 其他集群工具 291
10.9 Docker 292
10.9.1 Docker的性能 292
10.9.2 Docker的優(yōu)點(diǎn) 295
10.10 小結(jié) 296
第 11章 減少內(nèi)存占用量 297
11.1 基本類型對(duì)象的開銷很高 298
11.1.1 模塊array可高效地存儲(chǔ)大量的基本類型對(duì)象 299
11.1.2 使用NumExpr減少NumPy占用的內(nèi)存量 302
11.2 理解集合占用的內(nèi)存 305
11.3 比較字節(jié)和Unicode 307
11.4 在內(nèi)存中高效地存儲(chǔ)大量文本 307
11.5 使用scikit-learn FeatureHasher進(jìn)行文本建模 315
11.6 DictVectorizer和FeatureHasher簡(jiǎn)介 316
11.7 SciPy稀疏矩陣 319
11.8 減少內(nèi)存占用量的技巧 322
11.9 概率數(shù)據(jù)結(jié)構(gòu) 322
11.9.1 使用1字節(jié)的莫里斯計(jì)數(shù)器實(shí)現(xiàn)非常接近的計(jì)數(shù) 323
11.9.2 K最小值 326
11.9.3 布隆過濾器 329
11.9.4 LogLog計(jì)數(shù)器 335
11.9.5 實(shí)例 339
第 12章 實(shí)戰(zhàn)經(jīng)驗(yàn)教訓(xùn) 342
12.1 使用特征引擎簡(jiǎn)化特征工程流水線 342
12.1.1 機(jī)器學(xué)習(xí)中的特征工程 343
12.1.2 艱巨的特征工程流水線部署任務(wù) 343
12.1.3 利用開源Python庫(kù) 344
12.1.4 使用Feature-engine簡(jiǎn)化特征工程流水線的構(gòu)建和部署工作 344
12.1.5 推廣新的開源包 345
12.1.6 開發(fā)和維護(hù)開源庫(kù)及鼓勵(lì)積極投稿 346
12.2 表現(xiàn)出色的數(shù)據(jù)科學(xué)團(tuán)隊(duì) 347
12.2.1 需要多長(zhǎng)時(shí)間 347
12.2.2 探索和規(guī)劃 348
12.2.3 管理預(yù)期和交付 349
12.3 Numba 350
12.3.1 一個(gè)簡(jiǎn)單的示例 350
12.3.2 最佳實(shí)踐和建議 352
12.3.3 尋求幫助 355
12.4 優(yōu)化和思維 356
12.5 Adaptive Lab的社交媒體分析(2014) 358
12.5.1 Adaptive Lab的Python使用情況 358
12.5.2 SoMA的設(shè)計(jì) 358
12.5.3 開發(fā)方法 359
12.5.4 維護(hù)SoMA 359
12.5.5 給同行的建議 360
12.6 RadimRehurek網(wǎng)站如何讓深度學(xué)習(xí)快步如飛(2014) 360
12.6.1 管用的策略 360
12.6.2 優(yōu)化方面的經(jīng)驗(yàn)教訓(xùn) 362
12.6.3 結(jié)語(yǔ) 364
12.7 Lyst網(wǎng)站可用于生產(chǎn)環(huán)境的大規(guī)模機(jī)器學(xué)習(xí)(2014) 364
12.7.1 集群設(shè)計(jì) 364
12.7.2 發(fā)展迅猛的初創(chuàng)公司中的代碼迭代 365
12.7.3 構(gòu)建推薦引擎 365
12.7.4 報(bào)告和監(jiān)控 365
12.7.5 一些建議 366
12.8 Smesh的大規(guī)模社交媒體分析(2014) 366
12.8.1 Python在Smesh中扮演的角色 366
12.8.2 平臺(tái) 367
12.8.3 實(shí)時(shí)高性能字符串匹配 367
12.8.4 報(bào)告、監(jiān)控、調(diào)試和部署 368
12.9 使用PyPy成功地實(shí)現(xiàn)Web和數(shù)據(jù)處理系統(tǒng)(2014) 369
12.9.1 使用的工具 370
12.9.2 數(shù)據(jù)庫(kù) 370
12.9.3 Web應(yīng)用 371
12.9.4 OCR和翻譯 371
12.9.5 任務(wù)分配和任務(wù)隊(duì)列 371
12.9.6 結(jié)語(yǔ) 372
12.10 Lanyrd的任務(wù)隊(duì)列(2014) 372
12.10.1 Python在Lanyrd扮演的角色 372
12.10.2 讓任務(wù)隊(duì)列表現(xiàn)出色 373
12.10.3 報(bào)告、監(jiān)控、調(diào)試和部署 373
12.10.4 給同行的建議 373