Search code examples
pythonpython-3.xtimeitf-string

Timeit: pass stmt argument with f-string format


I am trying to estimate the time for running an algorithm by timeit module. But I ran into a problem when passing the stmt argument with f-string. To demonstrate my problems, I create two simple functions to return Fibonacci number as an example:

def fibo_exponential(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    return fibo(n-1) + fibo(n-2)

def fibo_linear(n):
    List = [0]*3
    List[0] = 0
    List[1] = 1
    for i in range(2,n+1):
        List[2] = List[1] + List[0]
        List[0] = List[1]
        List[1] = List[2]
    return List[2]

from timeit import timeit

def time():
    print(timeit('fibo_linear(10)', 'from __main__ import fibo_linear', number=100000))
    print(timeit('fibo_exponential(10)', 'from __main__ import fibo_exponential', number=100000))
    print(timeit(f"{fibo_linear(10)}", 'from __main__ import fibo_linear', number=100000))
    print(timeit(f"{fibo_exponential(10)}", 'from __main__ import fibo_linear', number=100000))

The result is shown below:

time()                # The argument for stmt list below:
0.21902308000426274   # 'fibo_linear(10)'
2.1373995500034653    # 'fibo_exponential(10)'
0.0006944179913261905 # f"{fibo_linear(10)}"
0.0006128590030129999 # f"{fibo_exponential(10)}"

My question is that why is time different when using f-string format?


Solution

  • timeit takes the string that it's given, and evaluates it as python code.

    Note that f-strings are evaluated immediately. When you do

    f'{fibo_linear(10)}'
    

    and fibo_linear(10) would resolve to, say, 55, then the string resolves to '55'.

    So, in your first two examples, you're telling timeit to evaluate the following lines, as python code:

    'fibo_linear(10)'
    'fibo_exponential(10)'
    

    but in your second two examples, you're telling it to evaluate this:

    '55'
    

    which, of course, is nearly instantaneous. Because it's, y'know, a constant.


    In other words, f'{fibo_linear(10)}' == '55' is True.