pythontiming

%timeit equivalent in code


The magic command %timeit is great to measure code execution times in an interactive way. However, I want to get the result of %timeit in order to plot the results. timeit.timeit allows this as well, but does not have the automatic scaling of the number of iterations and the normalising of the result that %timeit has.

Is there a built in function that can time a piece of code, which also automatically adjusts the number of iterations it performs, and returns a normalised result?


Solution

  • The magic %timeit command offers a -o option:

    -o: return a TimeitResult that can be stored in a variable to inspect the result in more details.

    It will still print the result but also return the result so that it can be captured in a variable. The syntax for magic commands is a bit limited but you could collect different results in a list by assigning it to a variable and appending that variable to a list:

    res = []
    for i in range(3):
        a = %timeit -o 10*10
        res.append(a)
    # 10000000 loops, best of 3: 61 ns per loop
    # 10000000 loops, best of 3: 61.1 ns per loop
    # 10000000 loops, best of 3: 60.8 ns per loop
    

    and then access res:

    print(res)
    # [<TimeitResult : 10000000 loops, best of 3: 61.2 ns per loop>,
    #  <TimeitResult : 10000000 loops, best of 3: 61.3 ns per loop>,
    #  <TimeitResult : 10000000 loops, best of 3: 61.5 ns per loop>]
    

    Each of these results has several attributes, which might be of interest:

    print(res[0].all_runs)
    # [0.6166532894762563, 0.6102780388983005, 0.6370787790842183]
    print(res[0].best)
    # 6.102780388983005e-08
    print(res[0].compile_time)
    # 0.00020554513866197934
    print(res[0].loops)
    # 10000000
    print(res[0].repeat)
    # 3
    print(res[0].worst)
    # 1.1170931449020795e-06
    

    To plot for example the best times you need to create a new list containing the best values:

    res_best_times = [result.best * 1e9 for result in res] 
    # "* 1e9" to get the result in nanoseconds
    print(res_best_times)
    # [61.2, 61.3, 61.5]