How do I understand this big difference in speed:

A friend of mine found a huge difference in runtime speed between these two

n=10^7;
(*1*) Timing[x = Table[Sin[2.2];, {i, n}];]
(*2*) Timing[x = Table[Sin[2.2], {i, n}];]


On computer, I get

{5.682385, Null}
{0.205839, Null}

Just by removing the semi-colon, it makes the code run 20 times faster. How do I understand why that is?

• Presumably it is faster to construct and store into a packed machine double array than a regular expression array comprised of Null. Commented Dec 12, 2014 at 19:20
• @DanielLichtblau answer? Commented Dec 13, 2014 at 11:28
• @YvesKlett Giving it a go, but it's far from a complete answer. Commented Dec 13, 2014 at 21:50

I will guess that the time needed to create a stock a packed array is significantly faster than that for filling a regular expression, even if every element is Null. For one, it is possible that Table, being a function that holds it arguments, preprocesses to the point of knowing (well, suspecting) that everything is a machine double in the fast case, and mostly avoiding the main evaluator thereafter (in effect behaving as though one had used Compile, to the level of C code). Also there is the actual storing: once we are in the packed array world it is only a matter of indexing into an array of machine numbers, and this should only involve fast memory accesses. With an ordinary expression the accessing, and hence setting, will be less direct.
There may be other wrinkles associated with producing two values per iteration (the sine, and Null). If we create a table of exact values, like so, it is somewhere in between in speed: Timing[x3 = Table[Sin[2], {i, n}];]. Moreover the difference is not entirely about doing two evaluations, because this next variant is still faster than the one with the semicolon: Timing[x4 = Table[Sin[2]; Sin[3], {i, n}];]. So I guess there is something about handling the Null that adds a bit of complexity.
• I think it actually does compile in the fast case. SystemOptions["CompileOptions"] yields {"CompileOptions" -> {..., "TableCompileLength" -> 250}}. Commented Dec 13, 2014 at 22:39
• I guess it is lack of the autocompilation, not packed arrays. Table[Sin[2.2] + Sin[2.3];, {i, n}] is 2 times slower then Table[Sin[2.2];, {i, n}] with the same output. But, of course, autocompilation and packed arrays are closery related to each other. Commented Dec 14, 2014 at 0:34