Skip to content Skip to sidebar Skip to footer

Timeout On A Python Function Call Inside Timeit

I have a function, let's call it my_function(*args, **kwargs), that depending on the arguments passed to it takes anywhere from 30 seconds to many many hours (days). I have a list

Solution 1:

Based on the answer found in Timeout function using threading in python does not work. If you try it out on foo(x) it does indeed stop counting unlike the my previous answer.

import multiprocessing as mp
import timeit

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

    ifhasattr(args, "__iter__") andnotisinstance(args, basestring):
        args = args
    else:
        args = [args]    
    kwargs = {} if kwargs isNoneelse 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

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

deftimeit_timeout(command, setup='', TIMEOUT=10, default=None, err=.05):
    return timeout(Timeit, args=command, kwargs={'setup':setup},
                   TIMEOUT=TIMEOUT, default=default, err=err) 

Solution 2:

After some more fiddling I have a initial answer based on Timeout function using threading. I would still love to hear from anyone who has better ideas as I am still new to this.

deftimeout(func, args=None, kwargs=None, TIMEOUT=10, default=None, err=.05):
    if args isNone:
        args = []
    elifhasattr(args, "__iter__") andnotisinstance(args, basestring):
        args = args
    else:
        args = [args]

    kwargs = {} if kwargs isNoneelse kwargs

    import threading
    classInterruptableThread(threading.Thread):
        def__init__(self):
            threading.Thread.__init__(self)
            self.result = Nonedefrun(self):
            try:
                self.result = func(*args, **kwargs)
            except:
                self.result = default

    it = InterruptableThread()
    it.start()
    it.join(TIMEOUT* (1 + err))
    if it.isAlive():
        return default
    else:
        return it.result

deftimeit_timeout(command, setup='', TIMEOUT=10, default=None, err=.05):
    import timeit
    f = lambda: timeit.Timer(command, setup=setup).timeit(1)
    return timeout(f,TIMEOUT=TIMEOUT, default=default, err=err) 

if __name__ == '__main__':    
    from time import sleep
    setup = 'gc.enable()\nfrom time import sleep'for n inrange(1,15):
        command = 'sleep({})'.format(n)
        print timeit_timeout(command, setup=setup, default=float('Inf'))

Post a Comment for "Timeout On A Python Function Call Inside Timeit"