views:

730

answers:

5

When I run the code below outside of timeit(), it appears to complete instantaneously. However when I run it within the timeit() function, it takes much longer. Why?

>>> import timeit
>>> t = timeit.Timer("3**4**5")
>>> t.timeit()
16.55522028637718

Using: Python 3.1 (x86) - AMD Athlon 64 X2 - WinXP (32 bit)

+11  A: 

The timeit() function runs the code many times (default one million) and takes an average of the timings.

To run the code only once, do this:

t.timeit(1)

but that will give you skewed results - it repeats for good reason.

To get the per-loop time having let it repeat, divide the result by the number of loops. Use a smaller value for the number of repeats if one million is too many:

count = 1000
print t.timeit(count) / count
RichieHindle
Yep! I also recommend using `python -mtimeit` from a command line instead of timeit as a module -- the command line version has just too many handy little things you don't get from the module (repeating a varying number of times depending on how slow/fast is what you're measuring, for example: a great microbenchmarking technique, pity the module doesn't offer it -- etc, etc;-).
Alex Martelli
@Alex Your comment here isn't clear to me. Can you clarify what extra functionality is available on the CLI.
Tshepang
@Tshepang: CLI use of timeit picks the number of repetitions "magically" -- few for slow code being measured, more for faster code, a lot for very fast code -- nicely balancing accuracy and time it takes to get results.
Alex Martelli
@Alex: now that's totally kool. Thanks for sharing. This piece of info should be more explicitly stated a bit better in the lib reference. Anyways, you also made it sound like there's other nifty features; what are those?
Tshepang
@Tshepang, I can't think of other "cool features" here.
Alex Martelli
@Alex: "the command line version has just too many handy little things you don't get from the module" was as if there was more; maybe it's nitpicking, but can you clarify that part (or just edit it out).
Tshepang
@Tshepang: Run `python -mtimeit -h` to get full documentation. (And Alex can't edit his comment - comments are only editable for a short time after they are first created.)
RichieHindle
+4  A: 

Because timeit defaults to running it one million times. The point is to do micro-benchmarks, and the only way to get accurate timings of short events is to repeat them many times.

Ned Batchelder
+1  A: 

According to the docs, Timer.timeit() runs your code one million times by default. Use the "number" parameter to change this default:

t.timeit(number=100)

for example.

Jeff Bradberry
+1  A: 

Timeit runs for one million loops by default.

You also may have order of operations issues: (3**4)**5 != 3**4**5.

alberge
Thanks everyone. Very helpful. And yes, that was the intended order of operations.
HC
A: 
>>> 3**4**5

37339184874102004353295975418486658822540977678373400775063693172207904061726525
12299936889388039772204687650654314751581087270545921608585813513369828091873141
91748594262580938807019951956404285571818041046681288797402925517668012340617298
39657473161915238672304623512593489605859058828465479354050593620237654780744273
05821445270589887562514528177934133521419207446230275187291854328623757370639854
85319476416926263819972887006907013899256524297198527698749274196276811060702333
710356481L

whereas:

>>> (3**4)**5
3486784401L
Sinan Ünür