views:

93

answers:

2

I have the following script 186.py:

S=[]
study=set([524287])

tmax=10**7
D={}
DF={}
dudcount=0
callcount=0

def matchval(t1,t2):
    if t1==t2:
        global dudcount
        dudcount+=1
    else:
        global callcount
        callcount+=1
        D.setdefault(t1,set([]))
        D.setdefault(t2,set([]))
        D[t1].add(t2)
        if t1 in D[t2]:
            DF.setdefault(t1,set([]))
            DF[t1].add(t2)
            DF.setdefault(t2,set([]))
            DF[t2].add(t1)

for k in xrange(27):
    t1=(100003 - 200003*(2*k+1) + 300007*(2*k+1)**3)%(1000000)
    S.append(t1)
    t2=(100003 - 200003*(2*k+2) + 300007*(2*k+2)**3)%(1000000)
    S.append(t2)
    matchval(t1,t2)

t1=(100003 - 200003*(55) + 300007*(55)**3)%(1000000)
S.append(t1)
t2=(S[31]+S.pop(0))%(1000000)
S.append(t2)
matchval(t1,t2)

for k in xrange(29,tmax+1):
    t1=(S[31]+S.pop(0))%(1000000)
    S.append(t1)

    t2=(S[31]+S.pop(0))%(1000000)
    S.append(t2)
    matchval(t1,t2)

D.setdefault(524287,set([]))
DF.setdefault(524287,set([]))
print D[524287]
print DF[524287]
print dudcount,callcount
print "Done"

The last line prints "Done" but python doesn't exit when this happens. I type the following command:

$ time python 186.py

And get the results:

set([810528L, 582178L, 49419L, 214483L, 974071L, 651738L, 199163L, 193791L])
set([])
11 9999989
Done

But I have to ctrl+C to get the time:

real    34m18.642s
user    2m26.465s
sys     0m11.645s

After the program outputs "Done" python CPU usage is very little... but the memory usage continues to grow... I used ctrl+C once it got to 80% of my system memory (its an old system).

What is going on here? What is the program doing after Done is printed? Shouldn't it be done?

Thanks, Dan

+5  A: 

I ran the same code on my 2 GHz dual-core laptop with 2GB RAM and it took about 1 1/2 minutes in Cygwin. The memory usage got up over 600 MB before the program quit and it took about 2-4 seconds after Done appeared for the prompt to come up and the memory to be released. However, I didn't see any memory increase after the Done appeared.

My guess is it has to do with memory management. After the Done appears, Python is working on freeing all of the memory which might take quite a while on an older machine with less RAM. I'm not sure why the memory actually increases unless there is just a delay in whatever is telling you how much memory is being used.

Justin Peel
+1 freeing memory - what I was just writing...
Andrew Aylett
Well I only have 480 MB of RAM. 1.4 GB of SWAP. Its still seems odd that it'd take 10X longer to clean the memory than actually run the program. Could the fact that I'm swapping (and you probably aren't) explain why the freeing memory process takes longer than the program itself?
Dan
Doing some further testing... This problem only applies when swapping occurs. I'm starting to think this isn't a code/python issue, but rather a system issue with harddrive write speeds or something... so probably is no longer a programming question. Thanks for your help.
Dan
+1  A: 

There are no indications in what you've posted that match the described symptoms. Perhaps the indentation in the executed code is stuffed and you are really about to run another loop around the whole pile. Note that only brave people are going to bother trying to reproduce your problem when it takes 34 minutes to run. Can you reproduce this problem in a shorter time?

When you did Control-C, what did the traceback say?

In any case, I'd strongly advise not having hard-coded constants(?) all over the place e.g. 524287 .... give it a meaningful name and do meaningful_name = 524287 at the start. Or if it's really a variable, feed it in via sys.argv.

John Machin
The program doesn't take 34 minutes to run. It takes ~2 minutes to run and then doesn't exit. I let it run for another 32 minutes before deciding to kill it. When I lower the value of tmax, it runs much faster, and doesn't have the same issue.
Dan
Oh. So it was swapping and you (a) didn't notice (b) noticed but thought it not worth mentioning?
John Machin
it was (a). I still don't fully understand how swapping explains this odd behavior... swap clearing should always go faster than swap writing, shouldn't it? How can the swap clearing take an order of magnitude longer than the original program?
Dan