文章

實戰 Python 效能分析 - 從 cProfile 到 py-spy

Python 應用(application)相較於 Go, C 這類語言所寫的應用,前者執行效率較慢是公認問題,不過 Python 的易用性也相對地提升開發速度,甚至其 batteries included 的哲學以及豐富的生態系也能夠減少重複造輪的情況,大幅縮短從概念到產品的實現路徑。

至於執行效率慢的問題,其實可以透過多種手段進行改善,譬如進行分散式、多執行緒(multithreading)、多行程(multiprocessing)、改善演算法,或以其他較高效率的語言為 Python 進行擴充(例如 ctypes 模組),雖然無法保證一定能夠像 Go, C 這類語言同樣高效,但也能夠將效率提升到可接受的程度以上。

但在處理真正的效率問題之前,絕大多數可能是我們沒有以正確有效率的方式撰寫 Python 應用,而導致其執行效率較差,並且將問題怪罪於 Python 本身。

因此如何剖析 Python 程式,並且找到隱藏在其中的效率問題,是一門相當重要的課題,本文將從介紹 cProfile 模組開始,並以實際範例找出 Python 程式中的問題點,並使用 py-spy 工具更近一步精準定位問題所在,以提高找出問題的效率。

Posted on  Dec 9, 2021  in  Python 程式設計 - 高階  by  Amo Chen  ‐ 5 min read

實戰 Fil 改善 Python 記憶體用量

用 Python resource 模組找出尖峰記憶體用量 一文介紹如何透過 Python resource 模組了解尖峰記憶體用量(peak memory usage), 不過該模組並無法提供更詳細的記憶體統計資料,無法得知具體哪部分的 Python 程式消耗大量記憶體,因此我們需要透過工具剖析(profiling)詳細的記憶體用量,以幫助定位問題之所在。

本文將介紹如何使用 Fil 剖析 Python 程式的記憶體用量,並透過 1 個簡單的範例,實際定位程式中耗用記憶體的部分,並進行改善優化。

Posted on  Nov 29, 2021  in  Python 程式設計 - 高階  by  Amo Chen  ‐ 3 min read

用 Python resource 模組找出尖峰記憶體用量

Python 先天的設計使然,所以 Python 相較起其他語言(如 Rust, Go 等)更加耗用記憶體,如果是簡單的 Python 程式(例如自動化腳本)基本不需要太在意記憶體的問題,但如果是需要計較運算資源成本的應用場景,例如使用 AWS, GCP 雲端服務等, Python 的記憶體耗用肯定會對總體花費造成影響,因此了解你的應用使用記憶體的情形是相當重要的一步。

如果要優化記憶體的使用,可先從盤點尖峰記憶體的用量著手,除了可以避免使用等級過高的運算資源之外,還可以針對尖峰用量最大的應用優先降低用量。

Python 也提供內建的 resource 模組可使用,讓開發者可以設定系統資源的使用限制(例如 CPU time, heap size, nice 值 等等),也可以讀取系統資源使用的情況,其中就包含尖峰記憶體(peak memory)用量的資訊。

Posted on  Nov 15, 2021  in  Python 程式設計 - 高階  by  Amo Chen  ‐ 2 min read

Docker multi-stage builds 教學

Docker 映像檔(image)大小在 production 環境中也是相當重要的一環。

如果 Docker 映像檔太大,不僅佔用傳輸頻寬,也會拉長部署(deployment)的時間,因此如何優化 Docker 映像檔案大小是一門重要課題。

優化 Docker 映像檔大小有若干種方法,其中一種為 multi-stage build, 不過 Docker 官方文件所提供的 multi-stage builds 範例卻無法正常運作,本篇將修正該範例並實際體驗 multi-stage builds 的效果。

Last updated on  Dec 30, 2022  in  Docker  by  Amo Chen  ‐ 3 min read

用 grep 搭配正規表示式擷取字串

grep 是長春實用的指令,每當需要從大量日誌(log)/資料中找出含特定字串的資料行時, grep 無疑是你的好幫手。

不過 grep 會將符合條件的資料行整行列出,因此如果只想要擷取符合的字串,就需要結合正規表示式(regular expression)中的幾個方法。

Posted on  Oct 8, 2021  in  Unix-like 命令列教學  by  Amo Chen  ‐ 2 min read

分分鐘教你學會使用 Python AIOHTTP

Python 知名套件 requests 一直是每位 Python 應用開發者在開發 HTTP client 的首選,不過該套件原生並不支援 asyncio, 無法受益於 asyncio 在 I/O 方面高效率的優點,因此如要增加使用 requests 的效率,通常會搭配 multiprocessing 或 threading 模組,透過平行(concurrent)處理提高同一時間能夠執行 HTTP 要求的數量。

所幸我們仍有 AIOHTTP 可以使用,該套件不僅提供與 requests 套件相同的功能,更原生支援 asyncio, 因此可以在不使用 multiprocessing 或 threading 模組的情況下,就能夠達到相當高的執行效率,如果想透過 asyncio 提高 HTTP client 的效能,不妨考慮使用 AIOHTTP 吧!

本文將透過實際範例學習如何使用 AIOHTTP 實作 HTTP client, 建議需有 asyncio 的基礎再閱讀本文為佳。

Last updated on  Aug 30, 2024  in  Python 模組/套件推薦 , Python 程式設計 - 高階  by  Amo Chen  ‐ 10 min read

Python asyncio shield 函式說明

前陣子研究 asyncio 模組時,恰好看到其中 1 個函式 wait_for() ,該函式在 coroutine 超過時限時,會將其取消(cancel),不過 asyncio 也有提供 1 個函式能夠保護 task 被取消,該函式為 shield() ,官方文件對於 shield() 函式的說明為:

Protect an awaitable object from being cancelled .

簡而言之,能夠防止 awaitables(coroutines, Tasks, Futures) 物件被取消。

不過,實際上該怎麼使用,官方文件並沒有著墨太多,因此本文將實際透過幾個範例摸索如何使用 shield() .

Posted on  Aug 15, 2021  in  Python 程式設計 - 高階  by  Amo Chen  ‐ 2 min read

Python asyncio 從不會到上路

自從 Python 3.4 推出 asyncio 模組之後,開發者在提升 Python 程式效能的解決方案上又多了 1 種選擇。

不過相較於較為人所熟知的 multiprocessing 與 threading 而言,大多數初學者並不習慣非同步式(asynchronous)式的開發思維,但只要能夠掌握 asyncio 模組中幾點重要的概念,即使是從未接觸過的初學者,也能夠慢慢掌握 asyncio 的使用方式。

本文將重點介紹 asyncio 模組中的重要概念,並透過實際範例理解 asyncio 的運作,從而學會如何使用 asyncio 模組。

Last updated on  Jul 1, 2024  in  Python 程式設計 - 高階  by  Amo Chen  ‐ 13 min read