# Why does Do or Table really slow down this code?

I have some function that usually executes pretty quickly:

logf[x_, y_] := N[f[x, y], 40] /. v_ :> (PutAppend[Unevaluated[f[x, y] = v;], "myfile.txt"];);

where f[x,y] is some other function (I can go into more detail if needed). Basically the above function logf[x,y] just has the task of writing the result of f[x,y] to file in the format f[1,1/10]=1.256488;

This executes pretty quickly :

logf[1, 60/10] // AbsoluteTiming
{0.59307800000000000000000000000000000000000000000000, Null}
logf[1, 61/10] // AbsoluteTiming
{1.28585800000000000000000000000000000000000000000000, Null}

Yet if I try to run a few using Table or Do then things massively slow down for some reason:

Table[logf[1, \[Omega]], {\[Omega], 60/10, 61/10, 1/10}] // AbsoluteTiming
{134.5075240000000000000000000000000000000000000000000, {Null, Null}}

and similarly with Do.

Why would this be happening?

If I use Map things are not so slow:

logf[1, #] & /@ {60/10, 61/10} // AbsoluteTiming
{1.7253110000000000000000000000000000000000000000000, {Null, Null}}

If this is the way to go, how can I map on both elements i.e. get the equivalent of Table[flog[x,y],{x,60/10,70/10,1/10},{y,0,10}]? Would that somehow use MapThread?

EDIT (if you really want to see the f[x,y] under the hood):

Definitions:

M = 1;
$MinPrecision = 50; rstar[r_] := r + 2 M Log[r/(2 M) - 1]; \[Lambda][l_] = l (l + 1); rinf = 15000; ninfphase = 100; rH = 20000001/10000000; nH = 200;$HistoryLength = 0;
$workingDirectory = "/someDir";$runningLogFile1 = "myfile.txt";
If[FileExistsQ[$runningLogFile1], Get[$runningLogFile1],
Export[\$runningLogFile1, "", "Text"];];

Equation to solve:

eq[\[Omega]_,
l_] := \[CapitalPhi]''[r] + (2 (r - M))/(
r (r - 2 M)) \[CapitalPhi]'[
r] + ((\[Omega]^2 r^2)/(r - 2 M)^2 - \[Lambda][l]/(
r (r - 2 M))) \[CapitalPhi][r] == 0;

Solve with an ansatz and get some coefficients (I then save these as an .mx and usually read in each time so this doesn't affect timing of code)

Infinitycs = Module[{n = ninfphase, c},
Clear[c];
veqexp =
CoefficientList[
Series[1/
r (-2 - l r - l^2 r +
2 (r + I r^3 \[Omega]) Derivative[1][v][
r] + (-2 + r) r^2 Derivative[1][v][r]^2 + (-2 + r) r^2 (
v^\[Prime]\[Prime])[r]) /. {v'[r_] :>
Sum[-i c[i]/r^(i + 1), {i, 1, n}],
v''[r_] :>
Sum[i (i + 1) c[i]/r^(i + 2), {i, 1, n}]}, {r, \[Infinity],
n - 1}], r^-1];

Do[c[i] = c[i] /. Simplify[Solve[veqexp[[i]] == 0, c[i]][[1]]]; Print, {i, 1, n}] ; Table[c[i], {i, 1, n}]];

After the first run, write these to file so can just load in in future and comment out the above bit:

SetDirectory["/someDir"];
DumpSave["infcs100.mx", Infinitycs];

So in future just load in: << infcs100.mx

Then f[x,y] is defined:

f[ll_?IntegerQ, \[Omega]\[Omega]_?NumericQ] := Module[{c2},
Do[c2[i] =
Infinitycs[[i]] /. {l -> ll, \[Omega] -> \[Omega]\[Omega]}, {i, 1,
ninfphase}];
vtrunc = Sum[c2[i]/r^i, {i, 1, ninfphase}];
init = 1/r Exp[I \[Omega]\[Omega] rstar[r] + vtrunc] /. r -> rinf;
dinit =
D[1/r Exp[I \[Omega]\[Omega] rstar[r] + vtrunc], r] /. r -> rinf;
Clear[c2];
{init, dinit}]
-
You'll probably find that everything will speed up considerably if you create all the expressions first and then write them out in one go, rather than using PutAppend. –  image_doctor Nov 22 '12 at 8:53
Are you sure something else isn't going on here. For me logf[1, 61/10] // AbsoluteTiming returns {0.000147, Null}, and with omega undefined I get Table[logf[1, [Omega]], {[Omega], 60/10, 61/10, 1/10}] // AbsoluteTiming -> {0.000245, {Null, Null}}. What form does omega take and is there anything unusual about f ? –  image_doctor Nov 22 '12 at 9:10
omega is just numeric, i.e. typical value 61/10 say. f is reasonably complicated, so a second or two (like when it is run on its own or in Map is inline with my expectations), it's basically solving an equation for some coefficients then constructing a large sum) –  fpghost Nov 22 '12 at 9:16
How could I implement your first suggestion? Maybe memoize f[x,y] first then? –  fpghost Nov 22 '12 at 9:20
logf doesn't have a holding attribute by any chance, right? Btw, you used flog instead of logf in your map example, hope this is not the reason for the timing difference –  Rojo Nov 22 '12 at 10:48