みなさん、こんにちは。Crossinのプログラミング教室へようこそ。
多くの人がPythonは「遅い」言語だと思っていますが、実際、多くの場合、遅いプログラムの理由は言語ポットではありませんが、コードはうまく記述されていません。したがって、プログラムの実行中に、実行時間が長すぎたり、メモリが大きすぎたりする場合は、プログラムの実行を監視して問題のある領域を見つけ、最適化する必要があります。今日は、日常生活で使用できるいくつかのPythonパフォーマンス分析ツールを共有します。
memory_profilerは、pythonプロセスを監視するためのアーティファクトです。関数にデコレータを追加するだけで、コードの各行のメモリ使用量を出力できます。
インストール:
pip install memory_profiler
使用する:
import time
@ profile
def my_func():
a =[1]*(10**6)
b =[2]*(2*10**7)
time.sleep(10)
del b
del a
print "+++++++++"if __name__ =='__main__':my_func()
出力:
$ python -m memory_profiler del3.py
+++++++++
Filename: del3.py
Line # Mem usage Increment Line Contents
================================================10.293 MiB 0.000 MiB @profile
def my_func():17.934 MiB 7.641 MiB a =[1]*(10**6)170.523 MiB 152.590 MiB b =[2]*(2*10**7)170.527 MiB 0.004 MiB time.sleep(10)17.938 MiB -152.590 MiB del b
10.305 MiB -7.633 MiB del a
10.309 MiB 0.004 MiB print "+++++++++"
import timeit
import time
def my_func():
time.sleep(1)returnsum([1,2,3])
result = timeit.timeit(my_func, number=5)print(result)
Jupyter Notebookでは、 %% timeit
マジックコマンドを使用して、セル内のコードの実行時間をテストできます。
%%timeit
import time
def my_func():
time.sleep(1)returnsum([1,2,3])
result = timeit.timeit(my_func, number=5)print(result)
Pythonのデコレータは、他の関数のコードを変更せずに関数を追加でき、ログの挿入、パフォーマンステスト、権限の検証などのシナリオでよく使用されます。タイミング関数をデコレータにカプセル化して、簡単に再利用できます。
from functools import wraps
import time
def timeit(func):
@ wraps(func)
def deco():
start = time.time()
res =func()
end = time.time()
delta = end - start
print("Wall time ", delta)return res
return deco
使用する:
@ timeit
def my_func():
# do something
time.sleep(3)
pass
出力:
Wall time:3
コードの全体的な実行時間を知りたいだけでなく、コードの各行の実行時間を正確に分析したい場合は、pythonのline_profilerモジュールが役立ちます。 line_profilerを使用して、関数などのコードの各行の応答時間をテストできます。使いやすさのために、line_profiler関連の関数をデコレータにカプセル化して使用できるため、インターフェイスの要求時にデコレータが実行され、結果が出力されます。
インストール:
pip install line_profiler
使用する:
from flask import Flask, jsonify
import time
from functools import wraps
from line_profiler import LineProfiler
# インターフェイスのコードの各行の実行時間を照会します
def func_line_time(f):
@ wraps(f)
def decorator(*args,**kwargs):
func_return =f(*args,**kwargs)
lp =LineProfiler()
lp_wrap =lp(f)lp_wrap(*args,**kwargs)
lp.print_stats()return func_return
return decorator
app =Flask(__name__)
@ app.route('/line_test')
@ func_line_time
def line_test():for item inrange(5):
time.sleep(1)for item inxrange(5):
time.sleep(0.5)returnjsonify({'code':200})if __name__=='__main__':
app.run()
出力:
* Running on http://127.0.0.1:5000/
Timer unit:1e-06 s
Total time:7.50827 s
File:/home/rgc/baidu_eye/carrier/test/flask_line_profiler_test.py
Function: line_test at line 22
Line # Hits Time Per Hit % Time Line Contents
==============================================================
@ app.route('/line_test')
@ func_line_time
def line_test():633.05.50.0for item inrange(5):55005225.01001045.066.7 time.sleep(1)631.05.20.0for item inxrange(5):52502696.0500539.233.3 time.sleep(0.5)1282.0282.00.0returnjsonify({'code':200})127.0.0.1--[05/Mar/201815:58:21]"GET /line_test HTTP/1.1"200-
上記のコード実行時間テストツールと比較すると、pyheatは、matplotlib描画ヒートマップを介してコードの実行時間を表示します。これは、より直感的です。
インストール:
pip install py-heat
指示:
pyheat <path_to_python_file>--out image_file.png
heartrateは視覚的な監視ツールでもあり、心拍数の監視などのプログラムの実行を追跡し、Webページを通じてPythonプログラムの実行プロセスを視覚化できます。
img
左側の数字は、コードの各行がトリガーされた回数を示しています。長いボックスは、最近トリガーされたコード行を示します。ボックスが長いほど、トリガーの数が多くなり、色が薄いほど、最近トリガーされます。このツールは、コードの各行の実行回数を記録します。
特定の実行時間ではなく、パフォーマンスのデバッグ中に少し味がありません
インストール:
pip install --user heartrate
使用する:
import heartrate
from heartrate import trace, files
heartrate.trace(browser=True)trace(files=files.path_contains('my_app','my_library'))
上記は、一般的に使用されるいくつかのPythonパフォーマンス最適化ツールです。ただし、このツールは単なる補助であり、コアは、コードの最適化を認識し、言語とコードを深く理解するために、コードを作成する必要があります。これは長期的な蓄積プロセスです。コードの読み取りと書き込みを継続すると、コードのパフォーマンスは自然に能力とともに向上し続けます。