Yes, there is! Mathematica creates a LibraryFunction
when compiling to C, but puts it in a temporary directory. If you can recover the library, you can load it as often as you like!
First let's define the function as in the question:
generatef[opt_] :=
Compile[{}, Module[{j = 0}, Do[j++, {i, 10^8}]; j], CompilationTarget -> opt];
f2 = generatef["C"];
Now take the expression f2
, and replace the heads of CompiledFunction
and LibraryFunction
with List
. The last bit tells us all the information we need to load function again with LibraryFunctionLoad
:
f2List = (f2 /. {CompiledFunction -> List, LibraryFunction -> List})
(* {{10, 10.1, 5468}, {}, {{2, 0, 2}}, {{0, {2, 0, 0}},
{100000000, {2, 0, 1}}, {1, {2, 0, 4}}}, {0, 8, 0, 0, 0},
{{6, 0, 2}, {6, 1, 3}, {6, 0, 5}, {3, 4}, {6, 2, 6},
{12, 6, 4, 7}, {6, 7, 2}, {4, 5, 3, -3}, {1}},
Function[{}, Module[{j = 0}, Do[j++, {i, 100000000}]; j]], Evaluate,
{"...\\Mathematica\\ApplicationData\\
CCompilerDriver\\BuildFolder\\compiledFunction0.dll",
"compiledFunction0", {}, Integer}} *)
So now all we need to do is load up the library and run it, with next-to-no-difference in the timing.
f2[] // AbsoluteTiming
(* {0.589635 seconds, 100000000} *)
AbsoluteTiming[
mynewfunction = LibraryFunctionLoad @@ Last@f2List;
mynewfunction[]
]
(* {0.584785 seconds, 100000000} *)
Then you need to copy the file out of the temporary directory to a directory of your choice in order to preserve the DLL. Here I've chosen the notebook directory, but you could also put it in one of the directories in $LibraryPath
instead and then only have to specify the filename rather than a path.
CopyFile[f2List[[-1, 1]], ToString@NotebookDirectory[] <> "compiledFunction0.dll"]
myf2 = LibraryFunctionLoad[
ToString@NotebookDirectory[] <> "compiledFunction0.dll",
"compiledFunction0", {}, {Integer}];
In this example, the {}, {Integer}
refers to the input and output variables as per the documentation, which will obviously be different for different functions.
The final point to note is that trying to overwrite/delete the copied DLL can throw an error if you haven't unloaded the library function via LibraryFunctionUnload
first.
I've not tested it on OSX or Linux, but apart from the file extensions (.dll
, .dylib
, .so
) I presume it should all be the same.