Update: The optimizations so far have been excellent. And I've used Python 64 bit to get around the memory issue, but I came to the problem that 50,000,000+ causes my computer to use up more than it's 8 gigs of memory and freeze. I've update the times for 20,00,000 to 40,000,000 for divisorSieve. 40,000,000 capped out at just over 7 gigs of memory. So something will have to be done, perhaps by writing to file or serializing part of the array, to free up memory.
I've never run into this issue before so suggestions are welcome. I'll also be looking into this on my own so if I come up with something, I will update again. I really thank people for their help so far!
Original Post (just with results and code updated): I have two sieves that I wrote in python and would like help optimizing them if at all possible. The divisorSieve calculates the divisors of all numbers up to n. Each index of the list contains a list of its divisors. The numDivisorSieve just counts the number of divisors each index has but doesn't store the divisors themselves. These sieves work in a similar way as you would do a Sieve of Eratosthenes to calculate all prime numbers up to n.
def divisorSieve(n): divs = [[1] for x in xrange(0, n + 1)] divs[0] = [0] for i in xrange(2, n + 1): for j in xrange(1, n / i + 1, i): divs[j]divs[i * j].append(i) #changed from += [i] with speed increase. return divs def numDivisorSieve(n): divs = [1] * (n + 1) divs[0] = 0 for i in xrange(2, n + 1): for j in xrange(1, n / i + 1, i): divs[j]divs[i * j] += 1 return divs #Timer test for function if __name__=='__main__': from timeit import Timer n = ... t1 = Timer(lambda: divisorSieve(n)) print n, t1.timeit(number=1) -----n-----|--time(divSieve)--|--time(numDivSieve)-- 100,000 | 0.118300055981 333831560615 | 0.0687864651365187762331281 200,000 | 0.19642657212271700566026 | 0.133795795235362314797537 300,000 | 0 1.2794828015181643773714 | 0.2090971574355124339118 400,000 | 0 1.37709491820663861821235 | 0.273495055048748340797412 500,000 | 0.52753871991 2.06917832929 | 0.33962928407959312993718 600,000 | 0 2.56667506375652753840891 | 0 1.40610250668717777010636 700,000 | 0 3.68520401816301465945139 | 0 1.47162219319538268800149 800,000 | 0 3.75536356285449267338434 | 0 1.53857560490162560614543 900,000 | 0.85135473036 3.98145114138 | 0 1.62032624245883002270324 1,000,000 | 0 4.9628313740134809342539 | 0 2.67567363314110247496423 2,000,000 | 19.9085028301380035361075 | 1 4.3477209678459150618897 3,000,000 | 215.83754773901465184114 | 2 7.0388760340924799900479 4,000,000 | 321.818084219692197508864 | 2 10.716361261431484527586 5,000,000 | 427.775635379741910144928 | 3 12.36783977117670585308 6,000,000 | 533.713483547936597508864 | 4 15.04204671274226118057 7,000,000 | 639.643012999947509513591 | 4 18.719181439322902677738 8,000,000 | 746.625172917835065447534 | 5 21.389290912481247001928 9,000,000 | 853.605791192392574136966 | 6 23.069122037698988925173 10,000,000 | 960.575549853830628718044 | 6 26.766407911928588813211 2011,000,000 | 1666.2312259750121182435 | 29.4509693973 12,000,000 | 13 MemoryError | 32.48032002243228102258 3020,000,000 | 24 MemoryError | 56.25937799342527237669 30,000,000 | MemoryError | 2086.30578497238917332214 40,000,000 | 32.8265861168 MemoryError | 27118.0092311999457179822 50,000,000 | Out of MemoryMemoryError | 33149.7464085339526622815 60,000,000 | Out of MemoryMemoryError | 40181.5103277975627320396 70,000,000 | Out of MemoryMemoryError | 47214.252135037617467749 80,000,000 | Out of MemoryMemoryError | 54246.179025315723677614 90,000,000 | Out of MemoryMemoryError | 60279.71678982453308422 100,000,000 | Out of MemoryMemoryError | 67314.4218930771813166014 Results are pretty good and I'm happy I was able to get it this far, but I'm looking to get it even faster. If at all possible, I'd like to get 100,000,000 at a reasonable speed with the divisorSieve. Although this also brings into the issue that anything over 1912,000,000+ throws a MemoryError at divs = [[1] for x in xrange(0, n + 1)]) in divisorSieve. numDivisorSieve does allow the full 100,000,000 to run. If you could also help get past the memory error, that would be great.