本書針對(duì)有一定基礎(chǔ)的Python程序員,將指導(dǎo)讀者實(shí)現(xiàn)代碼優(yōu)化的各種方法。讀者將學(xué)習(xí)如何使用智能的算法,以及使用各種相關(guān)的技術(shù),例如numpy、cython、cpython等,以及各種多線程和多節(jié)點(diǎn)策略。市面上一致缺乏學(xué)習(xí)用Pyhton完成高度計(jì)算性任務(wù)的教程,而本書正是這方面不可多得的一本好書。
Python代碼僅僅能夠正確運(yùn)行還不夠,你需要讓它運(yùn)行得更快。通過探索設(shè)計(jì)決策背后的基礎(chǔ)理論,本書幫助你更加深刻地理解Python的實(shí)現(xiàn)。你將學(xué)習(xí)如何找到性能瓶頸,以及如何在大數(shù)據(jù)量的程序中顯著加快代碼。
如何利用多核架構(gòu)或集群的優(yōu)點(diǎn)?如何構(gòu)建一個(gè)在不損失可靠性的情況下具備可伸縮性的系統(tǒng)?有經(jīng)驗(yàn)的Python程序員將學(xué)到針對(duì)這些問題或者其他問題的具體解決方案,以及來自那些在社交媒體分析、產(chǎn)品化機(jī)器學(xué)習(xí)和其他場(chǎng)景下使用高性能Python編程的公司的成功案例。
通過閱讀本書,你將能夠:
■ 更好地掌握numpy、Cython和剖析器;
■ 了解Python如何抽象化底層的計(jì)算機(jī)架構(gòu);
■ 使用剖析手段來尋找CPU時(shí)間和內(nèi)存使用的瓶頸;
■ 通過選擇合適的數(shù)據(jù)結(jié)構(gòu)來編寫高效的程序
■ 加速矩陣和矢量計(jì)算;
■ 使用工具把Python編譯成機(jī)器代碼;
■ 管理并發(fā)的多I/O和計(jì)算操作;
■ 把多進(jìn)程代碼轉(zhuǎn)換到在本地或者遠(yuǎn)程集群上運(yùn)行;
■ 用更少的內(nèi)存解決大型問題。
“ 盡管P y thon在學(xué)術(shù)和工業(yè)領(lǐng)域很流行, 但人們也經(jīng)常由于Python程序運(yùn)行太慢而放棄它。本書通過全面介紹改善優(yōu)化Python計(jì)算速度和可擴(kuò)展性的策略,從而消除人們的這種誤
解!薄狫ake VanderPlas 華盛頓大學(xué)
Micha Gorelick在bitly公司從事與數(shù)據(jù)打交道的工作,并負(fù)責(zé)建立了快速前進(jìn)實(shí)驗(yàn)室(Fast Forward Labs),研究從機(jī)器學(xué)習(xí)到高性能流算法領(lǐng)域的問題。
Ian Ozsvald是ModelInsight.io的數(shù)據(jù)科學(xué)家和教師,有著超過十年的Python經(jīng)驗(yàn)。他在yCon和PyData會(huì)議上教授Python編程,這幾年一直在英國從事關(guān)于數(shù)據(jù)科學(xué)和高性能計(jì)算方面的咨詢工作。
目錄
第1章 理解高性能Python 1
1.1 基本的計(jì)算機(jī)系統(tǒng) 1
1.1.1 計(jì)算單元 2
1.1.2 存儲(chǔ)單元 5
1.1.3 通信層 6
1.2 將基本的元素組裝到一起 8
1.3 為什么使用Python 12
第2章 通過性能分析找到瓶頸 15
2.1 高效地分析性能 16
2.2 Julia集合的介紹 17
2.3 計(jì)算完整的Julia集合 20
2.4 計(jì)時(shí)的簡單方法——打印和修飾 24
2.5 用UNIX的time命令進(jìn)行簡單的計(jì)時(shí) 27
2.6 使用cProfile模塊 28
2.7 用runsnakerun對(duì)cProfile的輸出進(jìn)行可視化 33
2.8 用line_profiler進(jìn)行逐行分析 34
2.9 用memory_profiler診斷內(nèi)存的用量 39
2.10 用heapy調(diào)查堆上的對(duì)象 45
2.11 用dowser實(shí)時(shí)畫出變量的實(shí)例 47
2.12 用dis模塊檢查CPython字節(jié)碼 49
2.13 在優(yōu)化期間進(jìn)行單元測(cè)試保持代碼的正確性 53
2.14 確保性能分析成功的策略 56
2.15 小結(jié) 57
第3章 列表和元組 58
3.1 一個(gè)更有效的搜索 61
3.2 列表和元組 63
3.2.1 動(dòng)態(tài)數(shù)組:列表 64
3.2.2 靜態(tài)數(shù)組:元組 67
3.3 小結(jié) 68
第4章 字典和集合 69
4.1 字典和集合如何工作 72
4.1.1 插入和獲取 73
4.1.2 刪除 76
4.1.3 改變大小 76
4.1.4 散列函數(shù)和熵 76
4.2 字典和命名空間 80
4.3 小結(jié) 83
第5章 迭代器和生成器 84
5.1 無窮數(shù)列的迭代器 87
5.2 生成器的延遲估值 89
5.3 小結(jié) 93
第6章 矩陣和矢量計(jì)算 94
6.1 問題介紹 95
6.2 Python列表還不夠嗎 99
6.3 內(nèi)存碎片 103
6.3.1 理解perf 105
6.3.2 根據(jù)perf輸出做出抉擇 106
6.3.3 使用numpy 107
6.4 用numpy解決擴(kuò)散問題 110
6.4.1 內(nèi)存分配和就地操作 113
6.4.2 選擇優(yōu)化點(diǎn):找到需要被修正的地方 116
6.5 numexpr:讓就地操作更快更簡單 120
6.6 告誡故事:驗(yàn)證你的“優(yōu)化”(scipy) 121
6.7 小結(jié) 123
第7章 編譯成C 126
7.1 可能獲得哪種類型的速度提升 127
7.2 JIT和AOT編譯器的對(duì)比 129
7.3 為什么類型檢查有助代碼更快運(yùn)行 129
7.4 使用C編譯器 130
7.5 復(fù)習(xí)Julia集的例子 131
7.6 Cython 131
7.6.1 使用Cython編譯純Python版本 132
7.6.2 Cython注解來分析代碼塊 134
7.6.3 增加一些類型注解 136
7.7 Shed Skin 140
7.7.1 構(gòu)建擴(kuò)展模塊 141
7.7.2 內(nèi)存拷貝的開銷 144
7.8 Cython和numpy 144
7.9 Numba 148
7.10 Pythran 149
7.11 PyPy 151
7.11.1 垃圾收集的差異 152
7.11.2 運(yùn)行PyPy并安裝模塊 152
7.12 什么時(shí)候使用每種工具 154
7.12.1 其他即將出現(xiàn)的項(xiàng)目 155
7.12.2 一個(gè)圖像處理單元(GPU)的注意點(diǎn) 156
7.12.3 一個(gè)對(duì)未來編譯器項(xiàng)目的展望 157
7.13 外部函數(shù)接口 157
7.13.1 ctypes 158
7.13.2 cffi 160
7.13.3 f2py 163
7.13.4 CPython模塊 166
7.14 小結(jié) 170
第8章 并發(fā) 171
8.1 異步編程介紹 172
8.2 串行爬蟲 175
8.3 gevent 177
8.4 tornado 182
8.5 AsyncIO 185
8.6 數(shù)據(jù)庫的例子 188
8.7 小結(jié) 191
第9章 multiprocessing模塊 193
9.1 multiprocessing模塊綜述 196
9.2 使用蒙特卡羅方法來估算Pi 198
9.3 使用多進(jìn)程和多線程來估算Pi 199
9.3.1 使用Python對(duì)象 200
9.3.2 并行系統(tǒng)中的隨機(jī)數(shù) 207
9.3.3 使用numpy 207
9.4 尋找素?cái)?shù) 210
9.5 使用進(jìn)程間通信來驗(yàn)證素?cái)?shù) 221
9.5.1 串行解決方案 225
9.5.2 Na ve Pool解決方案 225
9.5.3 Less Na ve Pool解決方案 226
9.5.4 使用Manager.Value作為一個(gè)標(biāo)記 227
9.5.5 使用Redis作為一個(gè)標(biāo)記 229
9.5.6 使用RawValue作為一個(gè)標(biāo)記 232
9.5.7 使用mmap作為一個(gè)標(biāo)記 232
9.5.8 使用mmap作為一個(gè)標(biāo)記的終極效果 234
9.6 用multiprocessing來共享numpy數(shù)據(jù) 236
9.7 同步文件和變量訪問 243
9.7.1 文件鎖 243
9.7.2 給Value加鎖 247
9.8 小結(jié) 249
第10章 集群和工作隊(duì)列 251
10.1 集群的益處 252
10.2 集群的缺陷 253
10.2.1 糟糕的集群升級(jí)策略造成華爾街損失4.62億美元 254
10.2.2 Skype的24小時(shí)全球中斷 255
10.3 通用的集群設(shè)計(jì) 255
10.4 怎樣啟動(dòng)一個(gè)集群化的解決方案 256
10.5 使用集群時(shí)避免痛苦的方法 257
10.6 三個(gè)集群化解決方案 258
10.6.1 為簡單的本地集群使用Parallel Python模塊 259
10.6.2 使用IPython Parallel來支持研究 260
10.7 為魯棒生產(chǎn)集群的NSQ 265
10.7.1 隊(duì)列 265
10.7.2 發(fā)布者/訂閱者 266
10.7.3 分布式素?cái)?shù)計(jì)算器 268
10.8 看一下其他的集群化工具 271
10.9 小結(jié) 272
第11章 使用更少的RAM 273
11.1 基礎(chǔ)類型的對(duì)象開銷高 274
11.2 理解集合中的RAM使用 278
11.3 字節(jié)和Unicode的對(duì)比 280
11.4 高效地在RAM中存儲(chǔ)許多文本 281
11.5 使用更少RAM的竅門 290
11.6 概率數(shù)據(jù)結(jié)構(gòu) 291
11.6.1 使用1字節(jié)的Morris計(jì)數(shù)器來做近似計(jì)數(shù) 292
11.6.2 K最小值 295
11.6.3 布隆過濾器 298
11.6.4 LogLog計(jì)數(shù)器 303
11.6.5 真實(shí)世界的例子 307
第12章 現(xiàn)場(chǎng)教訓(xùn) 311
12.1 自適應(yīng)實(shí)驗(yàn)室(Adaptive Lab)的社交媒體分析(SoMA) 311
12.1.1 自適應(yīng)實(shí)驗(yàn)室(Adaptive Lab)使用的Python 312
12.1.2 SoMA的設(shè)計(jì) 312
12.1.3 我們的開發(fā)方法論 313
12.1.4 維護(hù)SoMA 313
12.1.5 對(duì)工程師同行的建議 313
12.2 使用RadimRehurek.com讓深度學(xué)習(xí)飛翔 314
12.2.1 最佳時(shí)機(jī) 314
12.2.2 優(yōu)化方面的教訓(xùn) 316
12.2.3 總結(jié) 318
12.3 在Lyst.com的大規(guī)模產(chǎn)品化的機(jī)器學(xué)習(xí) 318
12.3.1 Python在Lyst的地位 319
12.3.2 集群設(shè)計(jì) 319
12.3.3 在快速前進(jìn)的初創(chuàng)公司中做代碼評(píng)估 319
12.3.4 構(gòu)建推薦引擎 319
12.3.5 報(bào)告和監(jiān)控 320
12.3.6 一些建議 320
12.4 在Smesh的大規(guī)模社交媒體分析 321
12.4.1 Python在Smesh中的角色 321
12.4.2 平臺(tái) 321
12.4.3 高性能的實(shí)時(shí)字符串匹配 322
12.4.4 報(bào)告、監(jiān)控、調(diào)試和部署 323
12.5 PyPy促成了成功的Web和數(shù)據(jù)處理系統(tǒng) 324
12.5.1 先決條件 325
12.5.2 數(shù)據(jù)庫 325
12.5.3 Web應(yīng)用 326
12.5.4 OCR和翻譯 326
12.5.5 任務(wù)分發(fā)和工作者 327
12.5.6 結(jié)論 327
12.6 在Lanyrd.com中的任務(wù)隊(duì)列 327
12.6.1 Python在Lanyrd中的角色 328
12.6.2 使任務(wù)隊(duì)列變高性能 328
12.6.3 報(bào)告、監(jiān)控、調(diào)試和部署 328
12.6.4 對(duì)開發(fā)者同行的建議 329