timethis for 1: 9 wallclock secs ( 7.64 usr + 1.22 sys = 8.86 CPU) @ 0.11/s (n=1) #### use Benchmark qw(timethis); sub primes { my $upper = shift; return () unless defined($upper); $upper = int(abs($upper)); my $sqrt1 = sqrt($upper) + 1; my $sieve = ""; my @p = (2, 3, 5); my $n; my $iter = sub { if (@p) { $n = shift @p; } else { do { # only ends with 1, 3, 7, or 9 $n += ($n % 10 == 3) ? 4 : 2; } while vec($sieve, $n, 1); } return undef if $n > $upper; if ($n < $sqrt1) { for (my $m = $n**2; $m <= $upper; $m += $n) { vec($sieve, $m, 1) = 1; } } return $n; }; return $iter unless wantarray; my @gather; while (defined(my $x = $iter->())) { push @gather, $x; } return @gather; } timethis -1, sub { printf "count: %d\n", scalar(() = primes(3_000_000)) };