**Addendum**

If you just want the greatest 10 primes less than M, you can start from `Prime[PrimePi[M]-9]`

. By doing so, you gain a speed increase of 2 orders of magnitude when `M = 100000`

.

```
M = 100000;
m = PrimePi[M]
AbsoluteTiming[Table[Prime[k], {k, m - 9, m}]]
```

9592

{0.000171, {99877, 99881, 99901, 99907, 99923, 99929, 99961, 99971, 99989, 99991}}

Now backwards (after closing and re-opening *Mathematica* and defining `M`

and `m`

.).
This is 10 x slower than the above, but still faster than starting from `Prime[1]`

.

```
AbsoluteTiming[Table[Prime[k], {k, m, m - 9, -1}]]
```

{0.001467, {99991, 99989, 99971, 99961, 99929, 99923, 99907, 99901, 99881, 99877}}

One might expect that `NextPrime`

would provide an advantage. We restart *Mathematica* and find out that it is only marginally better than our last attempt.

```
AbsoluteTiming[NestList[NextPrime, Prime[m - 9], 9]]
```

{0.001193, {99877, 99881, 99901, 99907, 99923, 99929, 99961, 99971, 99989, 99991}}

**My Earlier answers about the order of the iterator**.

I conducted the following tests starting at `Prime[1]`

. Even though this is a very inefficient approach, the results will be easier to compare to those of the OP.

We want to rule out `Range`

so we take it out of the timing. Likewise, we set `M`

and `m`

first, before conducting the timing.

```
M = 100000;
m = PrimePi[M];
r1 = Range[1, m];
r2 = Range[m, 1, -1];
```

**Backwards request of primes much slower than forwards request** (the original observation)

```
r1 == Reverse[r2]
AbsoluteTiming[prms = Prime[#] & /@ r1;]
AbsoluteTiming[prms = Prime[#] & /@ r2;]
```

True

{0.009920, Null}

{0.354147, Null}

Puzzling. Yet absolutely consistent with what you observed.

It appears that `r1`

may be stored in a form that can be processed more quickly than `r2`

.

**Half backwards, Half forwards**: Only half as bad as all backwards.

Let's look a little deeper.

`r3`

is the sub-list of odd numbers, followed by the even numbers.

`r5`

is like `r3`

but the odd numbers were reversed.

```
r3 = Transpose[Partition[r1, 2]] // Flatten;
r4 = Transpose[Partition[r1, 2]];
r5 = Join[Reverse[r4[[1]]], r4[[2]]];
```

Let's time the processing of r3 and r5:

```
AbsoluteTiming[prms = Prime[#] & /@ r3;]
AbsoluteTiming[prms = Prime[#] & /@ r5;]
```

{0.012765, Null}

{0.205590, Null}

Half the numbers in r5 were ordered from larger to smaller.
The delay was about 1/2 the delay we saw when all numbers were ordered from larger to smaller.

Provisional conclusion: *Mathematica* "counts" primes forwards faster than backwards(?)

**Random Ordering**

```
r6 = RandomSample[r1, 9592];
AbsoluteTiming[prms = Prime[#] & /@ r6;]
```

{0.190770, Null}

The (pseudo)random ordering of numbers runs as fast as the backwards-forwards list!

**Lingering Question**: Why should a random ordering of numbers be faster to process than a "backwards request" for primes? I would have guessed that the random case would be at least as slow, or slower than the backward case.

P.S. @Szabolcs Please look at the results above and see whether they are consistent with your hunch. (I'm uncertain whether they are.) Perhaps *Mathematica* only stores the results of the final outcome. In this case the backwards request would receive no benefits.

**Szabolcs' suggestion**

Here are some orderings recommended by Szabolcs. Notice how the orderings increasingly move toward canonical ordering from least to greatest.

```
Table[{k, First@Timing[
Prime /@ Flatten@Reverse@Partition[Range[1, 20], k]]}, {k, 1, 10}];
Table[{k, Prime /@ Flatten@Reverse@Partition[Range[1, 20], k]}, {k, 1,10}]
```

And their respective timings:

```
Table[{k, First@Timing[Prime /@ Flatten@Reverse@Partition[Range[1, 20000], k];]}, {k, 1,10}]
```

{{1, 2.540567}, {2, 1.275608}, {3, 0.858899}, {4, 0.647391}, {5,
0.517372}, {6, 0.431639},
{7, 0.370851}, {8, 0.325734}, {9, 0.291674}, {10, 0.262256}}

Here's the canonical ordering:

```
First@Timing[Prime /@ Flatten@Partition[Range[1, 20000], 1];]
```

0.011894

5Probably

`Prime[n]`

makes use of results for`Prime[m], m < n`

, but it caches only a limited number of results. But this is just a guess and you have surely though of it already. – Szabolcs – 2012-12-05T22:24:31.310So with a clear memory, Prime[n] runs in O(n) time.. – cartonn – 2012-12-05T22:34:56.840

`Prime`

and`PrimePi`

are`Listable`

, they are automatically mapped over a list, thus you can simply write e.g.`Prime @ Range @ m`

instead of`Prime[#] & /@ Range[1, m]`

. – Artes – 2013-01-05T18:03:15.510