time function problem
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Thu Nov 27 19:59:13 EST 2008
On Thu, 27 Nov 2008 11:17:04 -0800, willie wrote:
> My code:
>
> from time import time
> def leibniz(terms):
>
>
> acc = 0.0
> num = 4.0 # numerator value remains constant in the series den = 1
> count = 0
> start_time = 0.0
This line is wrong. You're starting your timer at the Dawn Of Time, way,
way back at the Epoch. On my system, the Epoch is:
>>> time.asctime(time.gmtime(0))
'Thu Jan 1 00:00:00 1970'
The right way is to use start_time = time.time().
Now that you have an answer to your direct question, let me suggest
something different. Currently your function leibniz() does TWO things:
it calculates the Leibniz value, and it times how long it takes. As a
general rule, functions should only do ONE thing. You should strip out
the timing code from the Leibniz code, like this:
from time import time
def leibniz(numterms):
acc = 0.0
num = 4.0 # numerator value remains constant in the series
den = 1
for aterm in xrange(numterms):
# (-1) allows fractions to alternate between a + and a - value
nextterm = num/den * (-1)**aterm
acc = acc + nextterm
den = den + 2
return acc
def timer(function, arguments):
start = time.time()
x = function(arguments)
timetaken = time.time() - start
return timetaken
timer(leibniz, 100000)
This risks being inaccurate. The problem is that your computer is multi-
tasking, even if you're not. There's a thousand other processes running
in the background, and the time they take is included in the time you are
measuring.
Unfortunately, there's no completely accurate, easy way around that, but
you can minimize the problem by using the Python timeit module:
http://www.diveintopython.org/performance_tuning/timeit.html
http://www.python.org/doc/2.5.2/lib/module-timeit.html
Here's a trick to help you. The timeit module expects to be given the
function to be tested as a string, not as a function, but you've already
written the function once and it is a pain to have to write it again as a
string. How to work around this? Easy -- instead of using a setup string
that builds the function from scratch, use a setup string that *imports*
the function:
from timeit import Timer
# Do a quick test
t = Timer('leibniz(10)', 'from __main__ import leibniz')
print "Best time was: %f seconds", min(t.repeat())/1e6
# Do a long test
t = Timer('leibniz(10000)', 'from __main__ import leibniz')
print "Best time was: %f seconds", min(t.repeat(number=100))/100
On my computer, I get results of about 1e-5 seconds for 10 terms, and
0.01 seconds for 10,000 terms.
--
Steven
More information about the Python-list
mailing list