473,406 Members | 2,713 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

timeit module: am I missing something obvious?

When using the timeit module, you pass the code you
want to time as strings:

import timeit
t = timeit.Timer("foo(x, y)", \
"""from module import foo
x = 27
y = 45
""")
elapsed_time = t.timeit()

This is all very well, but it feels quite unnatural to
me. Why am I passing strings around when functions are
first class objects? Have I missed something obvious?

I understand that sometimes you have to pass strings,
because statements are NOT objects in Python. But what
about when your code doesn't use statements?

It seems to me it would be really useful to be able to
do something like this:

# this doesn't work...
import timeit
from module import foo
x = 27
y = 45
t = timeit.Timer(foo, args=[x, y])
elapsed_time = t.timeit()

instead of messing about with setup strings and the like.

Am I missing something obvious? Does this functionality
already exist? Is there a reason why it can't exist?

--
Steven.

Feb 20 '06 #1
2 2677
Steven D'Aprano wrote:
When using the timeit module, you pass the code you
want to time as strings:

import timeit
t = timeit.Timer("foo(x, y)", \
"""from module import foo
x = 27
y = 45
""")
elapsed_time = t.timeit()

This is all very well, but it feels quite unnatural to
me. Why am I passing strings around when functions are
first class objects? Have I missed something obvious?
You are supposed to time small pieces of code where a function call would be
a significant overhead.
I understand that sometimes you have to pass strings,
because statements are NOT objects in Python. But what
about when your code doesn't use statements?

It seems to me it would be really useful to be able to
do something like this:

# this doesn't work...
import timeit
from module import foo
x = 27
y = 45
t = timeit.Timer(foo, args=[x, y])
elapsed_time = t.timeit()

instead of messing about with setup strings and the like.

Am I missing something obvious? Does this functionality
already exist? Is there a reason why it can't exist?


Just do it :-)

I would suggest a slight modification:

t = timeit.Timer.for_function(foo, x, y, a=..., b=...)

And while you are at it you could also move the code that dynamically
adjusts the number of repetitions from the main() function into a Timer
method and make its invocation the default for the timeit() method. (If
that has not been done already, see
http://mail.python.org/pipermail/pyt...ry/059952.html)

Peter
Feb 20 '06 #2
Peter Otten <__*******@web.de> writes:
Steven D'Aprano wrote:
When using the timeit module, you pass the code you
want to time as strings: ....
This is all very well, but it feels quite unnatural to
me. Why am I passing strings around when functions are
first class objects? Have I missed something obvious?
You are supposed to time small pieces of code where a function call would be
a significant overhead.


I think it can be useful to time longer code as well.

Moreover, when you pass in strings, you have to ensure that
the namespace is set-up correctly, which can be awkward at
times. If you could pass in a function, this would often
be much easier.
Just do it :-)
Yes, please do!
I would suggest a slight modification:

t = timeit.Timer.for_function(foo, x, y, a=..., b=...)

And while you are at it you could also move the code that dynamically
adjusts the number of repetitions from the main() function into a Timer
method and make its invocation the default for the timeit() method.


I agree.

Moreover, I think the calibration could be improved a lot. What I use
is below. It would be great if something like this could be merged
into timeit.py...

Notice how quickly it locks onto an appropriate number of iterations.
(Only 3% of the time is spent on calibration.)
import timer
timer.timing("3*2/6", goal=0.5, repeat=3, verbose=True)

1 loops -> 1e-05 secs
49933 loops -> 0.0396 secs
630325 loops -> 0.499 secs
630325 loops -> 0.499 secs 0.5 secs 0.501 secs
630325 loops, best of 3 trials: 0.792 usec per loop

Dan
"""Uses timeit to benchmark code, quickly choosing number of iterations.

Differences:

- This can be used interactively from python, not just from the
command line.
- Doesn't use separate creation and timing steps.
- The algorithm for choosing the number of iterations is faster
and more accurate. It also allows for just 1 iteration.
- The result from the final pass through the convergence loop
is used as one of the samples, which saves time
(especially if repeat=1).

Sample usage:

import timer
timer.timing("sin(10)",setup="from math import sin",repeat=3)
import time
timer.timing("3*2/6",repeat=3,goal=0.5,timer=time.time)

To do:

- add support for passing in a function instead of a string.
"""

import timeit
import time

def timing(stmt="pass",
setup="pass",
repeat=1,
goal=None,
number=None,
timer=timeit.default_timer,
verbose=False,
precision=3):
'''Eval setup, and then time stmt.
goal is desired time in seconds, a float.
number is desired number of iterations.
At most one of goal and number can be specified.
If neither is specified, default to a goal of 1 second.
When number is not specified, it is determined in an
efficient way.
repeat is the total number of times to run the test.
timer is the timer to use.
if verbose, show information about calibration.
precision is the number of significant digits to display.
'''

t = timeit.Timer(stmt,setup,timer=timer)
r = []

if number != None and goal != None:
raise ValueError,'Only one of number and goal may be specified.'

if number == None:
if goal == None:
goal = 1.0
# determine number so that total time >= 90% of goal.
number = 1
x = 0.0
while x < 0.9*goal:
x = t.timeit(number)

if verbose:
print "%9d loops -> %.*g secs" % (number, precision, x)
if x == 0:
# 1e2 is chosen because this is a common resolution
# for time.clock. Make sure that number gets increased
# by at least one, to avoid an infinite loop.
number = max(number+1,int(number*1e2*goal))
elif x < 0.9*goal:
# If x is very small, goal/x is large (possibly inf);
# to be cautious we limit the ratio to 1e6.
# The +1 is to ensure that number increases by at least 1,
# since goal/x > 1.
number = int(number*min(1e6,goal/x)+1)
r=[x]
repeat -= 1

r.extend(t.repeat(repeat, number))

best = min(r)
if verbose:
print "%9d loops ->" % number,
print " ".join(["%.*g secs" % (precision, x) for x in r])
print "%9d loops, best of %d trials:" % (number, len(r)),
usec = best * 1e6 / number
if usec < 1000:
print "%.*g usec per loop" % (precision, usec)
elif usec < 1e6:
print "%.*g milliseconds per loop" % (precision, usec/1000)
else:
print "%.*g seconds per loop" % (precision, usec/1e6)
Feb 20 '06 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Dennis Benzinger | last post by:
I just played around with the new timeit module. Using the following code I get some strange results: import timeit def test(s): result = 0 for c in s: result += ord(c) return result
2
by: Roy Smith | last post by:
I'm playing with the timeit module, and can't figure out how to time a function call. I tried: def foo (): x = 4 return x t = timeit.Timer ("foo()") print t.timeit()
2
by: Aggelos I. Orfanakos | last post by:
Hello. Under Gentoo Linux, I issue: $ python timeit.py python: can't open file 'timeit.py' $ ls -al /usr/lib/python2.3/timeit.py -rw-r--r-- 1 root root 9833 Oct 19 02:17...
5
by: ChaosKCW | last post by:
Hi I was wondering if someone could help with the import statements needed to use the timeit module in the following code. I need to access the "cur" object. Thanks, import cx_Oracle...
12
by: Steven Bethard | last post by:
Ok, so I have a module that is basically a Python wrapper around a big lookup table stored in a text file. The module needs to provide a few functions:: get_stem(word, pos, default=None)...
5
by: rurpy | last post by:
Why doesn't the following work? It generates a "NameError: global name 'data' is not defined" error. import timeit global data data = env = "global data; x = data"
9
by: Phoe6 | last post by:
Hi, Following are my files. In the format: Filename ---- content ---- config1.txt
2
by: Steven D'Aprano | last post by:
The timeit module is ideal for measuring small code snippets; I want to measure large function objects. Because the timeit module takes the code snippet argument as a string, it is quite handy...
7
by: ssecorp | last post by:
I am not clear about the results here. from timeit import Timer import Decorators def fib(n): a, b = 1, 0 while n: a, b, n = b, a+b, n-1
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.