Jason White
Jason White

Reputation: 686

timeit.timer giving far different results when using it in my own function vs. calling it from the command line

I made a little function using timeit just so I could be lazy and do less typing which isn't panning out as planned.

The (relevant) code:

def timing(function, retries=10000, formatSeconds=3, repeat=10):
    """Test how long a function takes to run. Defaults are set to run
    10 times of 10000 tries each. Will display time as 1 of 4 types.
    0 = Seconds, 1 = milliseconds, 2= microseconds and 3 = nanoseconds.
    Pass in paramaters as: (function, retries=10000,formatSeconds=3, repeat=10)"""
    t = timeit.Timer(lambda: function)
    result = t.repeat(repeat=repeat,number=retries)
    rlist = [i/retries for i in result]

It runs fine but it keeps returning:

timeprofile.timing(find_boundaries(numpy.asarray(Image.open(
r'D:\Python\image\image4.jpg')),79))
    10 runs of 10000 cycles each: 
    Best time: 137.94764   Worst:158.16651  Avg: 143.25466 nanosecs/pass

Now, if I do from the interpreter:

import timeit
from timeit import Timer
t = timeit.Timer(lambda: (find_boundaries(numpy.asarray(Image.open(r'D:\Python\image\image4.jpg')),79)))
result = t.repeat(repeat=5,number=100)
result = [i/100 for i in result]

I end up with [0.007723014775432375, 0.007615270149786965, 0.0075242365377505395, 0.007420834966038683, 0.0074086862470653615], or about 8 milliseconds.

And if I run the profiler on the script, it also gives approximately the same result of about 8 milliseconds.

I'm not really sure what the problem is although I reckon it has something to do with the how it's calling the function. When I check the data in the debugger it shows the function as a dictionary with a len of 53, and each key contains 1 to 15 tuples with a pair of 2-3 digit numbers in each.

So, if anyone knows why it's doing that and would like to explain it to me, and how to fix it, that'd be great!

Upvotes: 1

Views: 705

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1124778

Yes, there is a difference. When you run:

timeprofile.timing(find_boundaries(numpy.asarray(Image.open(
    r'D:\Python\image\image4.jpg')),79))

You are not passing in a function reference. You are calling the function and instead are passing in the result of that call. You are timing staticresult instead of somefunction(with, arguments).

Move out the lambda:

timeprofile.timing(lambda: (find_boundaries(numpy.asarray(Image.open(
    r'D:\Python\image\image4.jpg')),79)))

This means you need to remove it from your timing function, and instead pass the function straight to the Timer() class:

t = timeit.Timer(function)

Upvotes: 3

Related Questions