[Tutor] List comprehension question
Richard D. Moores
rdmoores at gmail.com
Thu Nov 11 14:04:10 CET 2010
On Wed, Nov 10, 2010 at 02:35, Steven D'Aprano <steve at pearwood.info> wrote:
> Richard D. Moores wrote:
>>
>> On Tue, Nov 9, 2010 at 12:54, Steven D'Aprano <steve at pearwood.info> wrote:
>>>
>>> Richard D. Moores wrote:
>>>
>>>> See <http://tutoree7.pastebin.com/R82876Eg> for a speed test with n =
>>>> 100,000 and 100,000 loops
>>>
>>> As a general rule, you shouldn't try to roll your own speed tests. There
>>> are
>>> various subtleties that can throw your results right out. Timing small
>>> code
>>> snippets on modern multi-tasking computers is fraught with difficulties.
>>
>> Yes, but I thought that if I ran the tests the way I did, several
>> times and then reversing the order of the functions, and seeing that
>> the results were very similar, I could be pretty sure of my findings.
>> Could you point out where taking even that amount of care could lead
>> me astray?
>
> Well, the biggest problem is that you're re-inventing the wheel. But in
> truth, what you did was not terrible, particularly if you're using Python 3
> where range() is quite lightweight rather than a heavy operation that
> creates a big list.
>
> There are various traps when timing code:
>
> * There are commonly two functions you use for getting the time: time.time()
> and time.clock(). On Windows, the best one to use is clock(), but on other
> operating systems, you should probably use time(). The timeit module
> automatically chooses the right one for you.
Thanks for this! My memory had it reversed: time() best for windows;
clock() for the rest. So I'm now doing a lot of search and replace on
old scripts.
And I reread the timeit doc. I found this down at the bottom of
<http://docs.python.org/library/timeit.html#module-timeit>:
==========begin quote from timeit module doc=====================
To give the timeit module access to functions you define, you can pass
a setup parameter which contains an import statement:
def test():
"Stupid test function"
L = [i for i in range(100)]
if __name__=='__main__':
from timeit import Timer
t = Timer("test()", "from __main__ import test")
print(t.timeit())
========end quote from timeit module doc======================
Earlier in this thread you gave us/me this:
============begin wisdom from Steven=================
At the Python interactive interpreter, the most useful pattern I've found is:
from timeit import Timer
t = Timer("proper_divisors(n)",
"from __main__ import proper_divisors; n = 100000")
min(t.repeat(repeat=5, number=100000))
Or if you're happy with Python's defaults, that last line can be just:
min(t.repeat())
=======temporary end of wisdom from Steven=================
I find using that at the interactive prompt a bit onerous -- lots of
copy and pasting. And doubly so when comparing times for 2 or more
functions.
The timeit doc gave me the obvious idea of how to avoid the prompt and
also easily compare the times of 2 or more functions. I'd like to know
if doing it this way is correct: Please see
<http://tutoree7.pastebin.com/84u1fkgA>
Huh. Just realized that this timing method doesn't include the 5
repeats called for by Steven's method. So how about using a for loop?
As in <http://tutoree7.pastebin.com/J8bPKUqC>.
Dick
More information about the Tutor
mailing list