I want to measure the execution times between several print statements which give the same result (after reading a book on python which states that using f-strings is more efficient than using str.format() and % placeholders). My python is v 3.8.8.
here is my example:
name = 'Kimberley'
f'Hello, {name}, how is your day?' # method 1
'Hello, {0}, how is your day?'.format(name) # method 2
'Hello, %(who)s, how is your day?' % {'who': name} # method 3 which should be the slowest one.
so first I have tried this which does not work because 'name' is not defined within the function.
import timeit
name = 'Kimberley'
timeit.timeit(stmt= "f'Hello, {name}, how is your day?'")
then I have tried this, however it gives the similar results of 0:00:00.000038 for each of the methods.
from timeit import default_timer as timer
from datetime import timedelta
# method 1
start = timer()
name = 'Kimberley'
f'Hello, {name}, how is your day?'
end = timer()
print(timedelta(seconds=end-start))
...
#method 3
start = timer()
name = 'Kimberley'
'Hello, %(who)s, how is your lamb?' % {'who': name}
end = timer()
print(timedelta(seconds=end-start))
however, this is not right because the book says that method 1 , method 2 and method 3 take about 0.06, 0.16 and 0.21 milliseconds to execute, respectively.
So I wonder how can I use timeit() to measure the execution times correctly?
CodePudding user response:
default_timer
is not the best way to measure tiny pieces of code, since it can be easily affected by other system processes, and the time taken is so short it needs run multiple times to be significant.
Instead, use timeit.timeit
as follows, specifying test-specific variables inside a setup
block.
from timeit import timeit
setup = """
name = "Kimberley"
"""
method1 = """f'Hello, {name}, how is your day?'"""
method2 = """'Hello, {0}, how is your day?'.format(name)"""
method3 = """'Hello, %(who)s, how is your lamb?' % {'who': name}"""
method4 = """Hello, %s, how is your lamb?' % (name,)"""
for method in (method1, method2, method3, method4):
print(timeit(setup=setup, stmt=method))
# 0.0563660740153864
# 0.17292902698274702
# 0.18335944903083146
# 0.09785140998428687
Note of course that these times (ms) are the time for timeit
to execute each statement 1000000 times.
I've also added in method4
which is faster than 3
since it doesn't have to do the 'mapping' from who
to name
.
CodePudding user response:
I have discovered another way with globals=globals() following the solution above.
setup = "name = 'Kimberley'"
method1 = "f'Hello, {name}, how is your day?'"
method2 = "'Hello, {0}, how is your day?'.format(name)"
method3 = "'Hello, %(who)s, how is your day?' % {'who': name}"
method4 = "'Hello, %s, how is your day?' % (name,)"
for method in (method1, method2, method3, method4):
print(timeit(globals=globals(), stmt=method))