3
$\begingroup$

How can I improve significantly the speed of the following code?

nmax = 10000000;
r = Range[nmax];
res = ({#, #^2, If[Mod[#, 2] == 0, "even", "odd"]} & /@ r); // AbsoluteTiming

{15.3145, Null}
$\endgroup$

2 Answers 2

6
$\begingroup$
res = Transpose[{r, r^2, Mod[r, 2]}];

This is about 50 times faster than the original code on my machine and contains the same information. I replaced the strings by integers (0 or 1), because that allows one to use vectorization and packed arrays.

If you insist on the strings, you can try

res = Transpose[{r, r^2, {"odd", "even"}[[Mod[r, 2, 1]]]}];

which is still 5 times faster than the original code. But this also shows drastically that transposing an unpackedable array can be very expensive. (Run the code without Transpose and compare the runtime.)

$\endgroup$
1
  • $\begingroup$ Thank you. Your solution with the strings is on my computer about four times faster than my code. $\endgroup$
    – mrz
    Oct 4, 2020 at 19:14
3
$\begingroup$

Another trick, not so efficient.

nmax = 1000;
r = Range[nmax];
f[x_] := {x, x^2, If[EvenQ@x, "even", "odd"]};
SetAttributes[f, Listable];
res1 = (f@r); // AbsoluteTiming

{0.0026543, Null}

This is the origin code.

{0.003949, Null}

res1 == res2

True

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.