@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.)