Jinja2環境作成の最適化
-
03-07-2019 - |
質問
私のアプリケーションはGoogle App Engineで実行されており、CPU使用率が高いため、ほとんどのリクエストが常に黄色のフラグを取得しています。プロファイラーを使用して、 jinja2.Environment
インスタンスを作成するルーチンまで問題を追跡しました。
モジュールレベルでインスタンスを作成しています:
from jinja2 import Environment, FileSystemLoader
jinja_env = Environment(loader=FileSystemLoader(TEMPLATE_DIRS))
Google AppEngine操作モード(CGI)により、このコードはリクエストごとに実行できます(モジュールインポートキャッシュは、分単位ではなく数秒間モジュールをキャッシュするようです)。
環境インスタンスをmemcacheに保存することを考えていましたが、選べないようです。 FileSystemLoader
インスタンスはpickle化可能でキャッシュできるようですが、このアプローチではCPU使用率の大幅な改善は見られませんでした。
誰でも jinja2.Environment
インスタンスを作成するオーバーヘッドを減らす方法を提案できますか?
編集:以下は(関連する)プロファイラー出力の一部です。
222172 function calls (215262 primitive calls) in 8.695 CPU seconds
ncalls tottime percall cumtime percall filename:lineno(function)
33 1.073 0.033 1.083 0.033 {google3.apphosting.runtime._apphosting_runtime___python__apiproxy.Wait}
438/111 0.944 0.002 2.009 0.018 /base/python_dist/lib/python2.5/sre_parse.py:385(_parse)
4218 0.655 0.000 1.002 0.000 /base/python_dist/lib/python2.5/pickle.py:1166(load_long_binput)
1 0.611 0.611 0.679 0.679 /base/data/home/apps/with-the-flow/1.331879498764931274/jinja2/environment.py:10()
1回の呼び出しですが、私が見る限り(これはすべてのGAEベースのアプリで一貫しています)、リクエスト処理サイクル全体で最も高価です。
解決
Arminは、Jinja2テンプレートをPythonコードにプリコンパイルし、コンパイルされたテンプレートを本番環境で使用することを提案しました。そこで、そのためのコンパイラ/ローダーを作成しました。これにより、複雑なテンプレートのレンダリングが13倍速くなり、解析のオーバーヘッドがすべてなくなりました。リポジトリへのリンクに関する関連する議論は、こちら。
他のヒント
OK、人々、これは今日私が#pocooで得たものです:
[20:59] zgoda:こんにちは、jinja2環境の作成プロセスを最適化できるかどうかを知りたいのですが、問題-> Jinja2環境作成の最適化
[21:00] zgoda:「コールド」からのプロファイラー出力があります。アプリ-> http://paste.pocoo.org/show/107009/
[21:01] zgoda:および" hot" -> http://paste.pocoo.org/show/107014/
[21:02] zgoda:「コールド」環境を作成するためのCPUコストをいくらか下げることができるかどうか疑問に思っています。リクエスト
[21:05] mitsuhiko:zgoda:インポートしたモジュールにenv作成を入れます
[21:05] mitsuhiko:like
[21:05] mitsuhiko:yourapplication.utils import envから
[21:05] zgoda:すでに存在しています
[21:06] mitsuhiko:うーん
[21:06] mitsuhiko:問題は、テンプレートがアクセスごとに再コンパイルされることだと思います
[21:06] mitsuhiko:残念ながら、gaeは信じられないほど限られています。現在できることはたくさんありますか
[21:07] zgoda:私はjinja bytecacheで試しましたが、prod(devサーバー上で)では動作しません
[21:08] mitsuhiko:知っている
[21:08] mitsuhiko:appengineにはマーシャルがありません
[21:12] zgoda:mitsuhiko:ありがとう
[21:13] zgoda:私は何か間違ったことをしていると思っていましたが、これは最適化できます...
[21:13] mitsuhiko:zgoda:次回のリリースではappengineのサポートが改善されますが、aeの改善されたキャッシングを実装する方法はまだわかりません
ArminはAppEngineでのバイトコードキャッシングの問題を認識しており、GAEでのキャッシングを許可するためにJinja2を改善する計画を持っているようです。時間の経過とともに状況が良くなることを願っています。
このレシピ memcacheを使用してバイトコードをキャッシュできます。テンプレートファイルのコンテンツ自体をキャッシュすることもできます。すべて同じレシピで