2

I know I can use timeit like this:

timeit.timeit("f(x)", "from __main__ import f", number=100000)

And this will repeat f() 100000 times.

However, I'd like to do something like this:

timeit.timeit("f()", "from __main__ import f", duration=5000)

Which would repeat f() as much as necessary until it hits 5 seconds.

Is there something like this in timeit or would I have to craft a while-loop myself?

gberger
  • 2,813
  • 3
  • 28
  • 50

2 Answers2

0

No, there is no such option. Check out this open issue.

This is how it is done in timeit.main, which is called when you run something like python -m timeit ... (only including here the relevant part):

if number == 0:
    # determine number so that 0.2 <= total time < 2.0
    for i in range(1, 10):
        number = 10**i
        try:
            x = t.timeit(number)
        except:
            t.print_exc()
            return 1
        if verbose:
            print "%d loops -> %.*g secs" % (number, precision, x)
        if x >= 0.2:
            break

You can easily modify it to stop after some "total_time".

shx2
  • 61,779
  • 13
  • 130
  • 153
0

When run from the command-line,

python -mtimeit -s'from script import f, x' 'f(x)'

the timeit script finds the number of iterations needed to call the function for at least 0.2 seconds. Endolith has coalesced that code down to a function:

def timeit_auto(stmt="pass", setup="pass", repeat=3, duration=0.2):
    """
    https://stackoverflow.com/q/19062202/190597 (endolith)
    Imitate default behavior when timeit is run as a script.

    Runs enough loops so that total execution time is greater than 0.2 sec,
    and then repeats that 3 times and keeps the lowest value.

    Returns the number of loops and the time for each loop in microseconds
    """
    t = timeit.Timer(stmt, setup)

    # determine number so that 0.2 <= total time < 2.0
    for i in range(1, 10):
        number = 10 ** i
        x = t.timeit(number)  # seconds
        if x >= duration:
            break
    r = t.repeat(repeat, number)
    best = min(r)
    usec = best * 1e6 / number
    return number, usec

The timeit code in the standard library can be found here.

Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677