# Why, according to Timing, is this code so FAST?

Obviously (?) I have a problem with precision or something but MMA seems to be able to take the mean squared of a 1e7 long series of random reals in literally no time, unless I use RepeatedTiming which reports that the average time to do the mean squared is 10 nanoseconds. Since this machine is not Deep Thought, I'd would love to know what I have done wrong - and how to do it right.

Since my series is very long I typically use a compiled function to generate it, but for those without a C compiler, I have included an uncompiled definition that can be substituted (with appropriate mods), though it takes ~30s to generate 1e7 rands on this machine.

randCList[seed_Integer, length_Integer] :=
Block[{}, SeedRandom[seed];
Table[RandomReal[{$MinMachineNumber, Pi -$MinMachineNumber}], {n,
1, length}]];
randCListCompiled =
Compile[{{seed, _Integer}, {length, _Integer}, {min, _Real}, {max, _Real}}, Module[{n}, SeedRandom[seed];
Table[RandomReal[{min, max}], {n, 1, length}]],
CompilationTarget -> "C", "RuntimeOptions" -> "Speed"];


Here are the timing tests - note that I used different series and different seeds in an attempt to avoid any cacheing issues. Recall that Timing returns a two element list whose first element is the time in seconds for the operation timed (second is result, if any; otherwise Null).

First[Timing[aSeries = randCListCompiled[45872, 10000000, $MinMachineNumber,Pi -$MinMachineNumber]]]
First[Timing[bSeries = randCListCompiled[45873, 10000000, $MinMachineNumber, Pi -$MinMachineNumber]]]
Timing[Mean[aSeries]^2]
Timing[Mean[bSeries]^2]
cSeries = randCListCompiled[45874, 10000000, $MinMachineNumber, Pi -$MinMachineNumber];
RepeatedTiming[100, Mean[cSeries]^2]


And the results...

0.514803 (* Timing for generation of aSeries *)

0.499203 (* Timing for generation of bSeries *)

{0., 2.46784} (* Timing for mean squared of aSeries *)

{0., 2.46767} (* Timing for mean squared of bSeries *)

{1.*10^-8, 100} (* Average timing for mean squared of cSeries, 100 iterations *)


I checked the precision of the "0." above and it said MachinePrecision, so really zero.

Back of envelope calculation says according to RepeatedTiming that MMA is summing 1e7 random reals in 10ns, i.e. each addition is about 1e-15s (1 femtosecond).

I am not inclined to believe this ;) What's going on?

• Perhaps related: (14152), (98453) – Michael E2 Oct 13 '16 at 11:09
• @MichaelE2 14152 I didn't think relevant at first, because I was genuinely interested in CPU time, but after reading 98453 I see that spawned threads may not be timed so Timing does not seem very useful at all (MMA 10.1, Win 7 64 bit, BTW). I think that must be it, using AbsoluteTiming gives more sensible answers for the individual series, but RepeatedTiming, according to the docs "measures 'wall clock time' " and the result is not consistent AFAICT with AbsoluteTiming - by several orders of magnitude (I get 10-16ms for mean squared a or b, but its still 10ns for RepeatedTiming). – Julian Moore Oct 13 '16 at 11:18
• I think Timing is a legacy function from the single-core single-CPU days. AbsoluteTiming was introduced in V5, and I don't know of case when I would use Timing instead of AbsoluteTiming. Maybe there is one.... – Michael E2 Oct 13 '16 at 11:21
• You may be right about the legacy status and Timing should probably be retired, but still, AbsoluteTiming only sets an upper bound because of other things that may be happening to slow down MMA threads. – Julian Moore Oct 13 '16 at 11:24

According to RepeatedTiming documentation, ￼RepeatedTiming[expr,t] does repeated evaluation for at least t seconds. In your case, the expression is 100 and t is Mean[cSeries]^2 = 2.46779 when I evaluate it. So what you are looking at is the time required to print 100 which is reasonable I guess. In fact, if you check the first example
In[1]:= RepeatedTiming[1 + 1]