Python time measure function Python time measure function python python

Python time measure function


First and foremost, I highly suggest using a profiler or atleast use timeit.

However if you wanted to write your own timing method strictly to learn, here is somewhere to get started using a decorator.

Python 2:

def timing(f):    def wrap(*args):        time1 = time.time()        ret = f(*args)        time2 = time.time()        print '%s function took %0.3f ms' % (f.func_name, (time2-time1)*1000.0)        return ret    return wrap

And the usage is very simple, just use the @timing decorator:

@timingdef do_work():  #code

Python 3:

def timing(f):    def wrap(*args, **kwargs):        time1 = time.time()        ret = f(*args, **kwargs)        time2 = time.time()        print('{:s} function took {:.3f} ms'.format(f.__name__, (time2-time1)*1000.0))        return ret    return wrap

Note I'm calling f.func_name to get the function name as a string(in Python 2), or f.__name__ in Python 3.


After playing with the timeit module, I don't like its interface, which is not so elegant compared to the following two method.

The following code is in Python 3.

The decorator method

This is almost the same with @Mike's method. Here I add kwargs and functools wrap to make it better.

def timeit(func):    @functools.wraps(func)    def new_func(*args, **kwargs):        start_time = time.time()        result = func(*args, **kwargs)        elapsed_time = time.time() - start_time        print('function [{}] finished in {} ms'.format(            func.__name__, int(elapsed_time * 1_000)))        return result    return new_func@timeitdef foobar():    mike = Person()    mike.think(30)

The context manager method

from contextlib import contextmanager@contextmanagerdef timeit_context(name):    start_time = time.time()    yield    elapsed_time = time.time() - start_time    print('[{}] finished in {} ms'.format(name, int(elapsed_time * 1_000)))

For example, you can use it like:

with timeit_context('My profiling code'):    mike = Person()    mike.think()

And the code within the with block will be timed.

Conclusion

Using the first method, you can easily comment out the decorator to get the normal code. However, it can only time a function. If you have some part of code that you don't what to make it a function, then you can choose the second method.

For example, now you have

images = get_images()big_image = ImagePacker.pack(images, width=4096)drawer.draw(big_image)

Now you want to time the big_image = ... line. If you change it to a function, it will be:

images = get_images()big_image = None@timeitdef foobar():    nonlocal big_image    big_image = ImagePacker.pack(images, width=4096)drawer.draw(big_image)

Looks not so great...What if you are in Python 2, which has no nonlocal keyword.

Instead, using the second method fits here very well:

images = get_images()with timeit_context('foobar'):    big_image = ImagePacker.pack(images, width=4096)drawer.draw(big_image)


I don't see what the problem with the timeit module is. This is probably the simplest way to do it.

import timeittimeit.timeit(a, number=1)

Its also possible to send arguments to the functions. All you need is to wrap your function up using decorators. More explanation here: http://www.pythoncentral.io/time-a-python-function/

The only case where you might be interested in writing your own timing statements is if you want to run a function only once and are also want to obtain its return value.

The advantage of using the timeit module is that it lets you repeat the number of executions. This might be necessary because other processes might interfere with your timing accuracy. So, you should run it multiple times and look at the lowest value.