I am looking to compile some elementary functions to pseudo C-code by using Mathematica's built-in function Compile as efficiently as possible.

I am interested whether you can provide any improvements regarding the computation speed.

Random number generation

cf1 = Compile[{{n, _Integer, 0}}, 
   RandomVariate[NormalDistribution[0., 1.], n], 
   CompilationTarget :> "C", RuntimeOptions -> "Speed"];
cf2 = Compile[{{n, _Integer, 0}}, 
   Table[RandomVariate[NormalDistribution[0., 1.]], {n}], 
   CompilationTarget :> "C", RuntimeOptions -> "Speed"];

cf2 calls RandomVariabe n-times and is supposed to be slower than cf1. The computation speed is compared to calling RandomVariate[] directly:

n = 1; ntot = 10^7;
(Total /@ (Table[First[AbsoluteTiming[#[ntot]]], {i, 1, n}] & /@ {cf1,
     RandomVariate[NormalDistribution[0., 1.], ntot]]], {i, 1, n}]]/n

This gives on my machine:

Out[1]: {0.431025, 0.867050}
Out[2]: 0.339019

Create zero-array

cf1 = Compile[{{n, _Integer}}, Array[0. &, n], 
   CompilationTarget :> "C", RuntimeOptions -> "Speed"];
cf2 = Compile[{{n, _Integer}}, Table[0., {n}], 
   CompilationTarget :> "C", RuntimeOptions -> "Speed"];

(#[ntot]; // AbsoluteTiming // First) & /@ {cf1, cf2}
ConstantArray[0.,ntot]; // AbsoluteTiming // First

This gives on my machine:

Out[1]: {0.187200, 0.109200}
Out[2]: 0.031200


cf1 = Compile[{{n, _Integer}}, Sum[i, {i, 1, n}], 
   CompilationTarget :> "C", RuntimeOptions -> "Speed"];
cf2 = Compile[{{n, _Integer}}, Total[Table[i, {i, 1, n}]], 
   CompilationTarget :> "C", RuntimeOptions -> "Speed"];
cf3 = Compile[{{n, _Integer}}, 
   Block[{i}, i = 0; Table[i += m, {m, 1, n}]; i], 
   CompilationTarget :> "C", RuntimeOptions -> "Speed"];

nTot = 10^8;
(#[nTot]; // AbsoluteTiming // First) & /@ {cf1, cf2, cf3}
Sum[i, {i, 1, nTot}]; // AbsoluteTiming // First

This gives on my machine:

Out[1]: {0.094005, 1.284074, 0.095005}
Out[2]: 0.

Is there any way to improve the compiled functions or is this pretty much the maximum one can achieve in terms of the computation time?

Glad for any helpful discussion!

  • $\begingroup$ There is no point in compiling RandomVariate once more; like many other built-in functions, it is already compiled. $\endgroup$ – Henrik Schumacher Oct 24 '18 at 20:03
  • $\begingroup$ Moreover, you will get more reliable timings with RepeatedTiming. $\endgroup$ – Henrik Schumacher Oct 24 '18 at 20:06
  • $\begingroup$ I know, but I cannot use it as it was introduced in in 2015 (MMA 10.1). I still use version 9. So you suggest to create it outside of Compile and then inline it? I need these random numbers in a bigger program of mine, and thuas wanted it to create within the context of Compile. But I will check the timings with outside or inside creation. $\endgroup$ – Display Name Oct 25 '18 at 6:26

Your Answer

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

Browse other questions tagged or ask your own question.