目次

内包表記の使用

list や dict の各要素に対して何らかの処理を行うような場合は、内包表記を使用した方が高速

確認用コード

# coding: utf-8
"""内包表記の処理速度確認.

リストの各値に+Nする処理の速度をforループと内包表記で比較する。

"""

import time

def normal(list1, num):
    stime = time.time()
    result = []
    for i in list1:
        result.append(i + num)
    print('forループ - {}'.format(time.time() - stime))
    return result


def tuning(list1, num):
    stime = time.time()
    result = [i + num for i in list1]
    print('内包表記 - {}'.format(time.time() - stime))
    return result


if __name__ == '__main__':

    # 確認用のリスト
    list1 = range(10000)

    # forループ
    result1 = normal(list1, 2)

    # 内包表記
    result2 = tuning(list1, 2)

    # 一応結果が同じか確認
    print(result1 == result2)

結果確認

forループ - 0.001007080078125
内包表記 - 0.0006196498870849609
True

高階関数の使用

TODO:

ユニバーサル関数の使用

TODO:

グローバル変数を使用しない

ループや関数からグルーバル変数へのアクセスは控える。
どうしても必要な場合は、ループの外でいったんローカル変数に代入して使用する。

ループの中で自前の関数を呼ばない

他言語(Java等)より関数呼び出しのオーバーヘッドが大きい為、ループの中で繰り返し呼ばれるような関数はべた書きした方が速く動作する。
可読性向上の為だけに切り出したような関数はべた書きにしてしまった方が速い。
※処理にかかる時間は べた書き < 自モジュールで定義した関数の呼出 < 他モジュールで定義した関数の呼出

mymodule.py

def func1(num):
    """他モジュールで定義した関数."""
    return num * 2

call_func_cost.py

# coding: utf-8
"""関数の呼び出しコストを計測する."""

import time
import mymodule


def func1(num):
    """自モジュール内に定義した関数."""
    return num * 2


if __name__ == '__main__':

    loop = 1000000

    # 他モジュール内の関数呼び出し
    stime = time.time()
    counter = 0
    for i in range(loop):
        counter += mymodule.func1(i)
    print(time.time() - stime)

    # 自モジュール内の関数呼び出し
    stime = time.time()
    counter = 0
    for i in range(loop):
        counter += func1(i)
    print(time.time() - stime)

    # べた書き
    stime = time.time()
    counter = 0
    for i in range(loop):
        counter += (i * 2)
    print(time.time() - stime)

確認結果

python3 call_func_cost.py

0.17288494110107422
0.1537008285522461
0.09762096405029297

大きな変数は使用後にdelする

numba(jitコンパイラ) による高速化

リストやデータフレームに対する&color(red){数値計算}を繰り返し、大量に行なうようなケースでは Numba を使用すれば劇的に改善する場合がある。
ただ、数値計算以外の処理は殆どパフォーマンスは変わらない。(処理によっては遅くなるケースも多々ある)

その他

同じ事を行う場合でも記述方法によってパフォーマンスは変わる

組み込み関数でも遅いものがあるので、別の方法で実現できないか検討する。
Pythonのstrptimeが遅い を参照。

list や dict の参照コストも考慮する

TODO:

可読性とはトレードオフな部分がある

TODO:

マルチスレッドは要検証

GIL問題により、マルチスレッドにした場合にかえって遅くなる場合がある。
マルチプロセスにして1プロセス:1スレッドにする方がだいたいのケースでうまくいく。
※コア数やメモリ量によって起動するプロセス数は考慮する事。


トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-07-30 (月) 07:23:51 (502d)