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?
>> Fortunately Python comes with that battery already included: the timeit
> module. You can use it from the shell like this:
>> python -m timeit -s "setup code goes here" "test code goes here"
>> 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())
That's terrific, Stephen! I've used timeit before, but only for really
small snippets. With your encouragement I experimented and after some
trial and error, I came up with this method for using your template:
1. Don't try to dump all you (Steven) wrote in at once.
2. First, do the import.
>>> from timeit import Timer
3. Then dump in the function (steps 2 and 3 can be reversed, I think)
4. then
>>>t = Timer("proper_divisors(n)",
"from __main__ import proper_divisors; n = 100000")
5. Finally,
>>>min(t.repeat(repeat=5, number=100000))
6. Wait for the result.
(please tell me if I could cut down the number of steps by combining a
couple of them.)
I was pleased that for
def proper_divisors(n):
pd = set((1,))
for x in range(2, int(n**.5)+1):
if n % x == 0:
pd.update((x, n//x))
return sum(list(pd))
I got 8.312734300029753
and for
def proper_divisors(n):
pd = set((1,))
for x in range(2, int(n**.5)+1):
factor, mod = divmod(n,x)
if mod == 0:
pd.update((x,factor))
return sum(list(pd))
got 14.859849506012608
That's about the same speed ratio (1.79) that I reported here earlier,
I believe. I quote: "It may be that I haven't done your suggestions
justice, but that
function is 76% slower than proper_divisors_sum2()"
Question: When I dump in more that one line of any code (properly
indented), after running it once, I've never known how to run it again
without a redump. The up arrow just gets me one line at a time. So,
how to do it?
Thanks,
Dick