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
シェルコマンドを実行します。
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()
呼び出しの前に以下の行を挿入することができます。
collectgarbage()
ここでは、開始時間を記録する前に完全な GC サイクルを強制的に実行します。
ただし、この例ではあまり役に立ちません。これは、タイミング計測対象のコードが多くの GC オブジェクトを作成しないためです。
不要な Lua テーブル検索操作を避けることで、target
関数をさらに高速化することができます。
local re_find = ngx.re.find
local function target()
re_find("hello, world.", [[\w+\.]], "jo")
end
しかし、ここでの違いは小さいかもしれません。
以上が本日お伝えしたい内容です。興味深く感じていただければ幸いです。
著者について
章亦春(Zhang Yichun)は、オープンソースの OpenResty® プロジェクトの創始者であり、OpenResty Inc. の CEO および創業者です。
章亦春(GitHub ID: agentzh)は中国江蘇省生まれで、現在は米国ベイエリアに在住しております。彼は中国における初期のオープンソース技術と文化の提唱者およびリーダーの一人であり、Cloudflare、Yahoo!、Alibaba など、国際的に有名なハイテク企業に勤務した経験があります。「エッジコンピューティング」、「動的トレーシング」、「機械プログラミング」 の先駆者であり、22 年以上のプログラミング経験と 16 年以上のオープンソース経験を持っております。世界中で 4000 万以上のドメイン名を持つユーザーを抱えるオープンソースプロジェクトのリーダーとして、彼は OpenResty® オープンソースプロジェクトをベースに、米国シリコンバレーの中心部にハイテク企業 OpenResty Inc. を設立いたしました。同社の主力製品である OpenResty XRay動的トレーシング技術を利用した非侵襲的な障害分析および排除ツール)と OpenResty XRay(マイクロサービスおよび分散トラフィックに最適化された多機能
翻訳
英語版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!