2

my_function(*args, **kwargs)渡された引数に応じて、30秒から数時間(日)かかる関数があります。さまざまな引数のリストがあり、引数を指定して関数がどれくらいの時間を要するかを知りたいです。

私はまだ を使用するtimeitのに非常に慣れていませんが、この部分を実行するのに十分なことを学びました。ただし、これは私の目的にはあまり効率的ではありません。完了するのに 4 時間以上かかる一連の議論は、すべて「有限」時間で解決できるにもかかわらず、扱いにくいと見なされます。引数の一部 (おそらくほとんど) の実行時間は 20 時間以上かかるため、4 時間後にテストを終了する方法を探しています。それは難治です。

私はTimeout on a Python function callStop code after time periodを見てきましたが、これは重複するのに十分近い質問かもしれませんが、これらの回答を統合するのに問題があるtimeitため、4時間未満の時間が次のように記録されます長時間の実行で 4 時間を超える有効な時間が返されるまでは、そうする必要があります。

これを行うための最良の方法は何ですか?

編集:func(*args,**kwargs)私が抱えていた問題の1つは、関数が次のようになっている間に、私が見た答えが取り入れられたことですtimeit:

timeit.Timer('my_function(*args, **kwargs)', setup=setup).timeit(1)

このフォームの処理方法がわかりません。

編集: スレッドを使用して以下に提供した元の回答は、実際にはスレッドを終了しません。これは、次の関数で実行することで簡単に表示できます。

def foo(x):
    for i in xrange(1, x + 1):
        sleep(1)
        print i
    return x

multiprocessing.Pool実際にはを含む を含むコードを使用すると、これがterminate()可能になります。

4

2 に答える 2

2

Python でのスレッド化を使用した Timeout 関数で見つかった回答に基づいては機能しません。試してみるとfoo(x)、以前の回答とは異なり、実際にカウントが停止します。

import multiprocessing as mp
import timeit

def timeout(func, args=(), kwargs=None, TIMEOUT=10, default=None, err=.05):

    if hasattr(args, "__iter__") and not isinstance(args, basestring):
        args = args
    else:
        args = [args]    
    kwargs = {} if kwargs is None else kwargs

    pool = mp.Pool(processes = 1)

    try:
        result = pool.apply_async(func, args=args, kwds=kwargs)
        val = result.get(timeout = TIMEOUT * (1 + err))
    except mp.TimeoutError:
        pool.terminate()
        return default
    else:
        pool.close()
        pool.join()
        return val

def Timeit(command, setup=''):
    return timeit.Timer(command, setup=setup).timeit(1)

def timeit_timeout(command, setup='', TIMEOUT=10, default=None, err=.05):
    return timeout(Timeit, args=command, kwargs={'setup':setup},
                   TIMEOUT=TIMEOUT, default=default, err=err) 
于 2013-12-31T19:55:33.140 に答える