在 OpenResty 中正確地測量 Lua 程式碼的執行時間
本教程演示了在 OpenResty 中對使用者 Lua 程式碼進行基準測試的正確方法和錯誤方法。
cd ~
mkdir time-lua
cd time-lua/
首先,要保證我們的 CPU 始終處於全速運轉狀態。
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
它通常預設取值 powersave
而我們需要設定成 performance
。
對一些 Lua 程式碼進行計時的最簡單方法是使用 time
命令和 resty
命令。
time resty -e 'ngx.re.find("hello, world.", [[\w+\.]], "jo")'
但這種方法有一個問題。resty
命令本身有一個啟動和退出的開銷。
time resty -e ''
我們可以看到在這臺機器上的開銷大約有 11 毫秒。
相反,我們應該使用 OpenResty 提供的ngx.now
Lua API函式。
restydoc -s ngx.now
讓我們把我們的 Lua 程式碼放到一個名為 ./bench.lua
的檔案中,以便更好地閱讀。
我們進行以下編輯:
- 首先,我們要確保 nginx 裡面的快取時間是最新的。
- 然後我們記錄的開始時間有毫秒的精度。
- 然後把我們前面提到的正則匹配呼叫。
- 然後我們再更新快取時間。
- 最後,透過做時間減法輸出經過的時間。
- 讓我們儲存檔案。
ngx.update_time()
local begin = ngx.now()
ngx.re.find("hello, world.", [[\w+\.]], "jo")
ngx.update_time()
ngx.say("elapsed seconds: ", ngx.now() - begin)
然後執行 resty
這個 shell 命令。
resty bench.lua
它記錄的延遲時間大約是 1 毫秒。但我們很快就會發現它很不準確。
正確的方法是在 bench.lua
檔案中做如下編輯:
- 把呼叫放到一個名為
target
的 Lua 函式中。 - 然後先呼叫這個函式 100 次作為熱身。現在這個
target
函式應該在這個迴圈執行完後進行 JIT 編譯。 - 然後在定時碼區域裡面,我們反覆呼叫 1000 萬次。
- 最後我們計算平均時間。
local function target()
ngx.re.find("hello, world.", [[\w+\.]], "jo")
end
for i = 1, 100 do
target()
end
ngx.update_time()
local begin = ngx.now()
local N = 1e7
for i = 1, N do
target()
end
ngx.update_time()
ngx.say("elapsed: ", (ngx.now() - begin) / N)
我們現在再次執行這個指令碼。
resty bench.lua
我們可以看到,每次呼叫僅僅是 30 納秒左右。比之前的結果快了很多很多倍!
實際上,我們可以進一步確保在我們給程式碼計時之前,沒有死掉的 GC 物件還沒有被回收,只要在第一個 ngx.update_time()
呼叫之前插入以下一行程式碼。只需在第一個 ngx.update_time()
呼叫之前插入以下一行程式碼。
collectgarbage()
在這裡,我們強制執行一個完整的 GC 週期,然後再記錄開始時間。
但是,它對我們這裡的例子沒有甚麼幫助。這是因為我們的定時程式碼無論如何也不會建立很多 GC 物件。
我們可以透過避免不必要的 Lua 表查詢操作,使 target
函式更快。
local re_find = ngx.re.find
local function target()
re_find("hello, world.", [[\w+\.]], "jo")
end
但這裡的差別可能比較小。
這就是我今天要講的內容。希望你覺得有趣。 如果你喜歡這個教程,請訂閱這個部落格網站和我們的 YouTube 頻道 或 B 站頻道。謝謝!
關於本文和關聯影片
本文和相關聯的影片都是完全由我們的 OpenResty Showman 產品從一個簡單的劇本檔案自動生成的。
關於作者
章亦春是開源 OpenResty® 專案創始人兼 OpenResty Inc. 公司 CEO 和創始人。
章亦春(Github ID: agentzh),生於中國江蘇,現定居美國灣區。他是中國早期開源技術和文化的倡導者和領軍人物,曾供職於多家國際知名的高科技企業,如 Cloudflare、雅虎、阿里巴巴, 是 “邊緣計算“、”動態追蹤 “和 “機器程式設計 “的先驅,擁有超過 22 年的程式設計及 16 年的開源經驗。作為擁有超過 4000 萬全球域名使用者的開源專案的領導者。他基於其 OpenResty® 開源專案打造的高科技企業 OpenResty Inc. 位於美國矽谷中心。其主打的兩個產品 OpenResty XRay(利用動態追蹤技術的非侵入式的故障剖析和排除工具)和 OpenResty Edge(最適合微服務和分散式流量的全能型閘道器軟體),廣受全球眾多上市及大型企業青睞。在 OpenResty 以外,章亦春為多個開源專案貢獻了累計超過百萬行程式碼,其中包括,Linux 核心、Nginx、LuaJIT、GDB、SystemTap、LLVM、Perl 等,並編寫過 60 多個開源軟體庫。
關注我們
如果您喜歡本文,歡迎關注我們 OpenResty Inc. 公司的部落格網站 。也歡迎掃碼關注我們的微信公眾號:
翻譯
我們提供了英文版原文和中譯版(本文) 。我們也歡迎讀者提供其他語言的翻譯版本,只要是全文翻譯不帶省略,我們都將會考慮採用,非常感謝!