Here's a Delphi implementation (not my weapon of choice but I gotta learn it somehow) that draws 100 random primes up to 1,000,000,000 in less than a millisecond:
function HighestPrimeNotAfter (n: Cardinal): Cardinal; const WINDOW_SIZE = 336; var is_composite: array of Boolean; max_factor, window_start: Cardinal; i, prime, start, stride, j, rest: Cardinal; begin SetLength(is_composite, WINDOW_SIZE); max_factor := Trunc(sqrt(n)); if n > WINDOW_SIZE then window_start := n - WINDOW_SIZE + 1 else window_start := 2; for i := Low(primes_up_to_64K) to High(primes_up_to_64K) do begin prime := primes_up_to_64K[i]; if prime > max_factor then BREAK; start := prime * prime; stride := prime shl (prime and 1); // no double-stepping for p == 2, because of the squaring if start >= window_start then j := start - window_start else begin rest := (window_start - start) mod stride; if rest = 0 then j := 0 else j := stride - rest; end; while j < WINDOW_SIZE do begin is_composite[j] := true; Inc(j, stride); end; end; for j := High(is_composite) downto Low(is_composite) do if not is_composite[j] then begin result := window_start + j; EXIT; end; assert(false); result := 0; // suppress compiler warning end; The timing includes 0.2 ms for sieving the primes up to 64K into an array of Cardinal, the code for which is trivial and not shown here.