[Python Flaskでmemory_profilerを使ってメモリ使用量を分析する

2019年1月29日火曜日

Flask Python

t f B! P L

[Python] Flaskでmemory_profilerを使ってメモリ使用量を分析する

Pythonでメモリ使用量を調査するには、「memory_profiler」が有名ですが、Flaskで利用するには、ひと手間加えてやる必要があります。

enter image description here

サンプルコード

早速、Flaskでmemory_profilerを使う為のサンプルコードを紹介します。
まず、調査対象のURL(関数)が呼ばれる度に、メモリ使用量をコントロールに表示するカスタムデコレータを作成します。

from functools import wraps

import memory_profiler
try:
    import tracemalloc
    has_tracemalloc = True
except ImportError:
    has_tracemalloc = False

def my_profiler(func=None, stream=None, precision=1, backend='psutil'):
    backend = memory_profiler.choose_backend(backend)
    if backend == 'tracemalloc' and has_tracemalloc:
        if not tracemalloc.is_tracing():
            tracemalloc.start()
    if func is not None:
        @wraps(func)
        def wrapper(*args, **kwargs):
            prof = memory_profiler.LineProfiler(backend=backend)
            val = prof(func)(*args, **kwargs)
            memory_profiler.show_results(prof, stream=stream,
                                         precision=precision)
            return val
        return wrapper
    else:
        def inner_wrapper(f):
            return profile(f, stream=stream, precision=precision,
                           backend=backend)
        return inner_wrapper

※上のコードは、こちらのページに書いてあった内容を引用してます。

あとは、上で作成したカスタムデコレータを、メモリ使用量の調査を行うFlaskの関数に設定すれば設定完了です。

@app.route('/sample'], methods=['GET', 'POST'])
@memory_profiler
def sample():
    #メモリ使用量の測定を行う処理
    print("TEST")

設定が完了したら、実際にURLにアクセスにしてみましょう!
以下の通り、コンソールに対象関数のメモリ使用量が出力されていると思います。

[実行結果]

Line #    Mem usage    Increment   Line Contents
================================================
    98     64.6 MiB     64.6 MiB   @app.route('/sample', methods=['GET', 'POST'])
    99                             @util.my_profiler
   100                             def sample():
   101                                 #メモリ使用量の測定を行う処理
   102     64.6 MiB      0.0 MiB       return "TEST"

本当に計測出来ているか試してみる

とりあえず、メモリ使用量のレポートが出力されました。
今度は、ちゃんと計測出来ているのか試してみました。

無意はありませんが、以下のような大容量の配列を作る処理で、測定してみます。

@app.route('/sample'], methods=['GET', 'POST'])
@memory_profiler
def sample():
    #メモリ使用量の測定を行う処理
    data = [i for i in  range(0, 1000000)]
    print("TEST")

[実行結果]

Line #    Mem usage    Increment   Line Contents
================================================
   100     65.0 MiB     65.0 MiB   @app.route('/sample', methods=['GET', 'POST'])
   101                             @know.util.my_profiler
   102                             def sample():
   103                                 #メモリ使用量の測定を行う処理
   104    103.8 MiB      0.8 MiB       data = [i for i in range(0, 1000000)]
   105
   106    103.8 MiB      0.0 MiB       return "TEST"

なんか測定出来ているっぽいです。

スポンサーリンク

QooQ