Write a function first_n_primes(n) that returns the first n prime numbers in ascending order.
Constraints:
-
1 ≤ n ≤ 100,000.
-
Aim for O(n log log n) expected time and near-linear memory.
-
Avoid repeated trial division per candidate; use an efficient sieve and a tight upper bound estimate for the nth prime.
-
Handle n=0 and n=1 edge cases cleanly.
-
Include unit tests for n ∈ {0,1,5,10,100,100000} and verify the last prime for n=100000 equals the known value.
-
Describe the complexity and key constants that dominate runtime for large n.