Suppose I have the following:
Table[x[i,j] = f[i,j], {i,1,10},{j,1,10}]; I want to set variables x[i,j] to have value f[i,j] where f can be anything. The Table (and you could also achieve this with a Map and I'm sure many other ways) produces an undesirable list which will be discarded. This is a waste of memory, especially if f produces some large object, and the copies will have to be garbage collected even though I've suppressed the output.
To avoid this behaviour for lists I would normally do a Scan like this example in the documentation:
test = Scan[(u[#] = x) &, {55, 11, 77, 88}] It sets u[55], u[11], u[77], u[88] without creating any intermediate lists and test is Null.
Compare this with a Map where test is populated with the values on the RHS of the Set. Also note this test return value is for illustrating the idea only and I expect to discard it:
test = Map[Set[u[#],x] &, {55, 11, 77, 88}]; Question:
How can I use
Scanover a multidimensional list such asTuples[Range[10],2]to achieve the same effect as theTableexample at the top of this question? I am not interested in using aForloop and I am only interested in achieving this withScanif that's possible.Are my fears about the discarded return values wasting memory and adding to garbage collection time justified if the object on the RHS of the
Setis very large? Can Mathematica tell when aTableorMapis about to discard the list they build up and avoid creating one? I suspect not e.g tryMaxMemoryUsed[Table[x, 300000];]
Update:
Scan appears to be consistently worse for memory usage, much to my surprise. Why? Surely it can't be because of the Range that must be constructed first, because MaxMemoryUsed[Range[10000]] is only 80376 bytes.
f[i_] := RandomReal[i, {64, 64}]; MaxMemoryUsed[Scan[(x[#] = f[#]) &, Range[10000]]] ClearSystemCache[]; MaxMemoryUsed[Table[y[i] = f[i], {i, 10000}]] ClearSystemCache[]; MaxMemoryUsed[Do[z[i] = f[i], {i, 10000}]] ClearSystemCache[];
Scanto begin with and the answer doesn't even use aScanso it's not that relevant. $\endgroup$Docan be thought of a as a drop-in replacement forTablewhen the list is not necessary. $\endgroup$For,Do,Whileetc. $\endgroup$(u[##] = f[##]) & @@@ {{4, 4}, {5, 2}, {4, 3}}(The latter are just some random sample locants) $\endgroup$test = (u[##] = f[##]) & @@@ {{4, 4}, {5, 2}, {4, 3}};is not Null. It creates a list of results which needs to be garbage collected - which is fine if the items produced byfare small, but slow if they are large. This is not an XY problem, I'm only interested in how to do it withScan- I already know several other ways to achieve the same effect as theMaporTableapproach. $\endgroup$