Passing function objects to timeit
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Sat Mar 29 22:23:07 EDT 2008
On Sat, 29 Mar 2008 21:12:33 -0300, Gabriel Genellina wrote:
> En Sat, 29 Mar 2008 07:33:40 -0300, Steven D'Aprano
> <steve at REMOVE-THIS-cybersource.com.au> escribió:
>
>> The timeit.Timer class times "code snippets" -- you pass it strings
>> rather than function objects. That's good for what it's worth, but
>> sometimes the code you want to time is too big to easily pass as a
>> string, or maybe you only have access to a function object without the
>> source, or for whatever reason it's not very convenient.
>>
>> In this case, a good trick is to import the function by name:
>>
>> timeit.Timer('spam()', 'from __main__ import spam')
>>
>>
>> But now I find myself wanting to time a function that's not defined in
>> __main__. Here's a illustrative example:
>>
>>
>> def factory():
>> def f():
>> return "spam"
>> return f
>>
>> def main():
>> func = factory()
>> return timeit.Timer('func()', 'from __main__ import func').timeit()
>
> Would this help (untested)?
>
> def main():
> return timeit.Timer('func()', 'from __main__ import factory; func =
> factory()').timeit()
Unfortunately no.
The above was just a simple illustration. Perhaps I misled you by showing
where func() came from, but what I intended to illustrate was that func()
could come from *anywhere*. I might not know where it came from: all I
have is a function object.
In fact, my question is actually more general than that, because my
example was a little unrealistic in that the function took no arguments.
I have to deal with the function arguments as well.
The general problem is that I wish to time an arbitrary function with
arbitrary arguments. The function and arguments are provided to me as
Python objects, but timeit requires strings. Converting the objects to
strings is not practical, and the objects might not exist in the __main__
module.
The problem is that timeit creates its own namespace to execute the code
in (which is a good thing!). Is there a way to insert arbitrary objects
into that namespace?
> Or maybe:
>
> def main():
> global func
> func = factory()
> return timeit.Timer('func()', 'from __main__ import func').timeit()
I'll try playing around with that and see.
--
Steven
More information about the Python-list
mailing list