# What is the fastest way to read a constant, read-only dataset from compiled function?

I need a compiled function $$f(\theta,\mathcal D)$$ that uses some variables $$\theta$$ and some data $$\mathcal D$$. I will be calling the function multiple times with different values of the variables, but with always the same data $$\mathcal D$$. I am trying to make the execution of the function as fast as possible.

Q: What is the best way to pass the data to the function to optimize the execution speed?

## Attempts

Based on what I would do in other languages, I would be inclined to define the data as a constant array, and use it in the function, but I'm, not sure about how to do this in Mathematica, nor if it would actually be better.

I have tried a couple of examples:

data = RandomReal[{0, 1}, 10^5];
f1 = Compile[{{d, _Real, 1}}, Total[d], CompilationTarget -> "C"];
f2 = Compile[{}, Total[data], CompilationTarget -> "C"];
f3 = Compile[{}, With[{d = data}, Total[d]], CompilationTarget -> "C"];


The running times, shown below, make clear that $$f_1$$ performs faster than $$f_2$$ and $$f_3$$. Neither $$f_2$$ nor $$f_3$$ seem to compile the data inside the function, despite data being defined at compile time. I say this after running

data = RandomReal[{0, 1}, 10^3];
f2[]
f3[]
data = RandomReal[{0, 1}, 10^3];
f2[]
f3[]


and observing that that both calls to $$f_2$$ and $$f_3$$ after redefining the data give different results.

On the other hand, the compile times of $$f_2$$ and $$f_3$$ increase with the size of the dataset, which suggests to me that the data is being compiled into the functions: So do $$f_2$$ and $$f_3$$ compile the data in any way? (This is not THE question, but an additional question that might be good to address to answer the main question).

• f2 and f3 aren't able to really take advantage of anything because data is a global, uncompilable variable Aug 4 at 21:48
• Have you considererd using the package << CompiledFunctionTools ? Then using CompilePrint to display what your functions are compiled. I agree with above, explore setting your function attribute to Listable. Then you could run your function over your data list. Aug 4 at 21:49
• Thanks @Shelton_swelton. Using CompilePrint on f2 and f3 shows an identical output. In both of them, the list of data points is included. What I don't understand then is why those functions are sensitive to changes of the variable data after compilation. Aug 4 at 22:00

You can inspect the generated code with CCodeStringGenerate. And it seems that f2 and f3 copies data into the code, that's why the compilation is so slow, but then the code makes a call to Kernel for the fresh values each time.
• You could circumvent this by using the With[{data=data}, Compile[...]] idiom but at that point there's barely a point to compiling in the first place since extra compilation time will swamp any downstream benefit I imagine Aug 4 at 21:55
• @b3m2a1 Thank you! It does work better than $f_2$ and $f_3$, and it does what I was attempting to do initially, but it is slightly (around 10%) slower than $f_1$, which still puzzles me. I would expect the fully compiled data to be the fastest, but I guess I'm wrong, or missing something. Aug 4 at 23:03