19

I would like to time a snippet of my code, and I would like just the CPU execution time (ignoring operating system processes etc).

I've tried time.clock(), it appears too imprecise, and gives a different answer each time. (In theory surely if I run it again for the same code snippet it should return the same value??)

I've played with timeit for about an hour. Essentially what kills it for me is the "setup" process, I end up having to import around 20 functions which is impractical as I'm practically just re-writing my code into the setup section to try and use it.

Cprofiles are looking more and more attractive, but do they return CPU time? also, a minor point - it outputs way too much information. Is there any way to get the outputted information into a txt or .dat file so I can actually read it?

Cheers

OS: Ubuntu Program: python 2.7

Nathan Bush
  • 1,401
  • 4
  • 13
  • 17
  • 4
    Note that you will get different times for every run, even if you want to count cpu cycles eaten only by your process. This is because of CPU cache, which will end up in different state (having different parts of your address space) every time. CPU cache is shared between processes, so you cannot guarantee that for example every time you will run your code, a certain variable will be kept in cache. – liori Mar 02 '13 at 16:38
  • [resource.getrusage](http://docs.python.org/2/library/resource.html) can be used to get process time in python 2.7 – AnnanFay Oct 04 '13 at 10:59

2 Answers2

23

It sounds like you are looking for a way to time the process-wide execution time, the best thing you can do is use timeit.default_timer() which offers the most precise time.clock() or time.time() function available on the current platform, but it is system-wide time, meaning that other proceses can interfere with your measurments.

Here's the info from the docs of timeit.default_timer():

Define a default timer, in a platform-specific manner. On Windows, time.clock() has microsecond granularity, but time.time()‘s granularity is 1/60th of a second. On Unix, time.clock() has 1/100th of a second granularity, and time.time() is much more precise. On either platform, default_timer() measures wall clock time, not the CPU time. This means that other processes running on the same computer may interfere with the timing.

You should try testing c-modules which might have access to different timing apis.


The best possible way to do this is by using time.process_time() which is only available in python 3.3 and up, here's the info from the docs:

Return the value (in fractional seconds) of the sum of the system and user CPU time of the current process. It does not include time elapsed during sleep. It is process-wide by definition. The reference point of the returned value is undefined, so that only the difference between the results of consecutive calls is valid.

Shedokan
  • 1,212
  • 1
  • 10
  • 21
  • 6
    Good answer, but `process_time` is only available in Python 3.3 and later, he's using 2.7. – omz Mar 02 '13 at 16:31
  • 4
    `timeit.default_timer()` is `time.perf_counter()` on Python 3.3+. Here're [`time.process_time()` and `time.perf_counter()` for Python 2 on Ubuntu.](https://gist.github.com/zed/5073409) – jfs Mar 02 '13 at 21:45
  • 1
    That is a great hack, you should post it as an answer – Shedokan Mar 02 '13 at 22:01
5

Instead of time.clock(), use timeit.default_timer(); it uses the most accurate option for your platform. For Ubuntu, for example, this will use time.time() instead.

When using timeit, create one setup function that you then can re-use for timeit. Yes, this looks like a bit of work but it ensures that you time what you really wanted to measure, and not include setup code in the time-critical measured section.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343