How do I create an array with random unique numbers in a specific range?

@btime (from BenchmarkTools.jl) is a much more reliable way to time fast calculations like this (it calls the code several times in a loop to ensure sufficient timer resolution, and then repeats the timing multiple times and reports the minimum time to reduce noise). It looks like @time is greatly overestimating the time for sample here:

julia> @btime sample(1:100000, 100, replace = false);
  2.285 μs (8 allocations: 3.60 KiB)

julia> @btime randperm(100000)[1:100];
  647.933 μs (3 allocations: 782.17 KiB)

julia> @btime shuffle(1:100000)[1:100];
  744.786 μs (3 allocations: 782.17 KiB)

and, for comparison, the first ChatGPT solution from above (modified to take parameters for the numbers):

julia> @btime generate_unique_random_integers(100000, 100);
  3.531 μs (11 allocations: 4.50 KiB)

(This is pretty fast! But beware that generate_unique_random_integers(k, n) by this algorithm is best when n \ll k so that the sampled integers are unique on the first try with high probability. For k - n \ll k, I think the expected runtime approaches \Theta(n^2). In fact, this is essentially the self_avoid_sample! algorithm in StatsBase.jl, which is used by sample for n \ll k unordered sampling without replacement.)

8 Likes