-1

ボトルネックを見つけるために cProfile でコードのプロファイリングを行ったところ、独特のボトルネックが見つかりました。

私のコードは次のように構成されています:

def A1Distance(a_list):
    #returns something

pr = cProfile.Profile()
pr.enable()
x = A1Distance(list_comprehension)
pr.disable()

cProfile では、合計 17.554 秒間実行されます。合計時間でトップの関数は次のとおりです。

ncalls  tottime  percall  cumtime  percall filename:lineno(function)

    1    9.884    9.884   17.554   17.554 Cov_Opt_Parallel.py:141(A1Distance)

ご覧のとおり、A1Distance は約 10 秒かかり、1 回呼び出されます。pr.enable() と pr.disable() を関数内に配置すると、同じ出力になりますが、A1Distance の 10 秒はありません。したがって、関数を呼び出すだけで 10 秒かかるように見えます。これの理由/修正について何か提案はありますか?

4

1 に答える 1

1

list_comprehension10 秒かかっているのはあなたです。関数への引数は、関数が呼び出される前に評価されるため、関数内でプロファイルを作成すると、コストのかかる作業list_comprehensionは既に完了しています。

たとえば、これを参照してください。

import time, cProfile

def func_a(a_list):
    return len(a_list)

def func_b(a_list, pr):
    pr.enable()
    ret = len(a_list)
    pr.disable()
    return ret


def main():
    pr = cProfile.Profile()
    pr.enable()
    func_a([time.sleep(x) for x in range(3)])
    pr.disable()
    pr.print_stats()

    pr = cProfile.Profile()
    func_b([time.sleep(x) for x in range(3)], pr)
    pr.print_stats()

    pr = cProfile.Profile()
    pr.enable()
    [time.sleep(x) for x in range(3)]
    pr.disable()
    pr.print_stats()

if __name__ == '__main__':
    main()

次のような出力が得られます:

     7 function calls in 3.006 seconds

Ordered by: standard name

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.000    0.000 tmp.py:3(func_a)
    1    0.000    0.000    0.000    0.000 {len}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    1    0.000    0.000    0.000    0.000 {range}
    3    3.006    1.002    3.006    1.002 {time.sleep}


     2 function calls in 0.000 seconds

Ordered by: standard name

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.000    0.000 {len}
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


     5 function calls in 3.004 seconds

Ordered by: standard name

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    1    0.000    0.000    0.000    0.000 {range}
    3    3.004    1.001    3.004    1.001 {time.sleep}
于 2015-10-08T02:22:41.220 に答える