6
$\begingroup$

In the process of playing around with Compile, I discovered something surprising. RandomReal[{-1, 1}, 3] is a lot slower than Compile[{}, RandomReal[{-1, 1}, 3]]. What could account for this? I would have imagined the two would have similar speeds.

Here's exactly what I did. First a simple timer:

compareTiming[f1_, f2_, its_] :=
 With[{
   tf1 = First@AbsoluteTiming[Scan[f1, Range[its]]], 
   tf2 = First@AbsoluteTiming[Scan[f2, Range[its]]]},
  (tf2 - tf1)/Max@{tf1, tf2}
  ]

then:

In[115]:= randomReal3 = Compile[{}, RandomReal[{-1, 1}, 3]];
randomReal3U = Function[RandomReal[{-1, 1}, 3]];
compareTiming[randomReal3[] &, randomReal3U, 10^6]

Out[117]= 0.131774

So the compiled form is 13% faster than the uncompiled form? But RandomReal is built-in and so I would have assumed is already implemented at the C level. What could be causing this?

I understand that I can, of course, generate a huge list of random vectors using RandomReal[{-1, 1}, {10^8, 3}] or something but it would be nice to know why, when I need to get a large number of random vectors one at a time (absent something like storing $10^8$ of then and pulling randomly) the fastest way to do this is with a compiled version of a built-in function.

$\endgroup$
  • 5
    $\begingroup$ Compile does some argument checking during the compilation, which RandomReal[] might do at run-time. Also, getting just 3 random numbers means the overhead is a higher proportion. With a sample size of 300000, I get that the uncompiled version is faster. $\endgroup$ – Michael E2 Jan 7 '17 at 23:18
  • $\begingroup$ I get a different results if I use Do instead of Scan, too. $\endgroup$ – Michael E2 Jan 7 '17 at 23:20
  • $\begingroup$ The first comment makes me feel better. I was expecting the user-compiled version to be slower. The second is just fascinating. What do you think is causing that? $\endgroup$ – b3m2a1 Jan 7 '17 at 23:21
  • $\begingroup$ You mean Do[i, {i, Range[10^6]}], yes? But I too get that it's much faster to use the Do imp. $\endgroup$ – b3m2a1 Jan 7 '17 at 23:29
  • $\begingroup$ I don't have a good idea....Yeah I was just going to fix that...It's not clear that different overheads explain which method is faster, though. $\endgroup$ – Michael E2 Jan 7 '17 at 23:30
5
$\begingroup$

For 10^6 calls, the difference of RandomReal and the compiled version is 0.279 s on my machine. That makes a difference of 279 ns per call which is really next to nothing.

To show you, where the difference comes from, consider the following completely unrelated example

compareTiming[f1_, f2_, its_] := 
 With[{
   tf1 = First@RepeatedTiming[Do[f1[], {its}]], 
   tf2 = First@RepeatedTiming[Do[f2[], {its}]]},
   (tf2 - tf1)/Max[tf2, tf1]
 ]

testC = Compile[{}, 0];
test[] := 0;

compareTiming[testC, test, 10^6]
(* -0.2 *)

Here, the compiled version is slower. Now, we throw the overhead of another high-level function call in:

f[] := 0;
test[] := f[];

compareTiming[testC, test, 10^6]
(* 0.27 *)

This suggests that the difference in runtime does not come from creating the random vector, but it comes from the interpreter evaluating the function f (or RandomReal) as it has to access the DownValues of this function

$\endgroup$
  • $\begingroup$ The thing is, I'm intentionally not using any functions with DownValues. In fact the compiled form I supplied should be even slower for the fact that I wrapped it in a Function call so it's calling Function then CompiledFunction at each step. I agree it's unlikely that the issue comes from actually generating the vector. I assume those functions are the same. $\endgroup$ – b3m2a1 Jan 8 '17 at 4:50
  • $\begingroup$ But your definition of randomReal3U contains a Function as well. So this has to evaluate Function and then RandomReal. Have you tried what you get with compareTiming[randomReal3[] &[] &, randomReal3U, 10^6] which adds another layer of Function to the compiled call? $\endgroup$ – halirutan Jan 8 '17 at 5:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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