First, range
uses the Python int
class, which can overflow (as you have experienced). The function srange
uses the Sagemath Integer
class instead, which will not overflow. Second, using sample
is probably not a good idea. On my somewhat old computer:
sage: %time sample(srange(2^24), 7)
CPU times: user 4.11 s, sys: 556 ms, total: 4.66 s
Wall time: 6 s
sage: %time sample(srange(2^25), 7)
CPU times: user 8.95 s, sys: 1.34 s, total: 10.3 s
Wall time: 14.2 s
[14635440, 2287708, 14649651, 26289169, 18124119, 30825037, 17257883]
sage: %time sample(srange(2^26), 7)
CPU times: user 17.1 s, sys: 2.34 s, total: 19.5 s
Wall time: 23 s
[9787083, 12313568, 7761365, 8998698, 55334892, 50923481, 65747342]
It seems to be roughly doubling in time as the argument to srange
doubles. (The issue is that srange
actually constructs the whole list first.) Needless to say, I don't want to try 2^130
. Much faster is to use randint
repeatedly (and the changes of getting the same integer twice are pretty small:
sage: %time [randint(1, 2^130) for n in range(7)]
CPU times: user 63 µs, sys: 1 µs, total: 64 µs
Wall time: 67 µs
[1341203791323696537546187325304798025292,
1106243203902472361349055754890433865742,
1038420201477214469366016121149956168427,
1242849022616461088502016645925189018763,
286347095973575864665046785261064404737,
286152873235140220458041877475917123637,
41617504738350918940022502684766969623]
This is almost instant. The command A = [randint(1, 2^100000000) for n in range(7)]
took almost a second for me. It actually takes longer to print the elements of A. Also, you could write a loop instead to make absolutely sure you don't get any repetitions, or test it afterwards, but it's probably not necessary if you're using such large sample sizes.