({{, (RefLink[Compile, paclet:ref/Compile])[{(Subscript[x, 1]),(Subscript[x, 2]),…},expr]
creates a compiled function that evaluates expr assuming numerical values of the (Subscript[x, i]). }, {, (RefLink[Compile, paclet:ref/Compile])[{{(Subscript[x, 1]),(Subscript[t, 1])},…},expr]
assumes that (Subscript[x, i]) is of a type that matches (Subscript[t, i]). }, {, (RefLink[Compile, paclet:ref/Compile])[{{(Subscript[x, 1]),(Subscript[t, 1]),(Subscript[n, 1])},…},expr]
assumes that (Subscript[x, i]) is a rank (Subscript[n, i]) array of objects, each of a type that matches (Subscript[t, i]). }, {, (RefLink[Compile, paclet:ref/Compile])[vars,expr,{{(Subscript[p, 1]),(Subscript[pt, 1])},…}]
assumes that subexpressions in expr that match (Subscript[p, i]) are of types that match (Subscript[pt, i]). }})

OpenersNotesSection(Spacer1)Details and Options

The types handled by (RefLink[Compile, paclet:ref/Compile]) are:

Nested lists given as input to a compiled function must be full arrays of numbers.

(RefLink[Compile, paclet:ref/Compile]) handles numerical functions, matrix operations, procedural programming constructs, list manipulation functions, and functional programming constructs, etc.

(RefLink[Compile, paclet:ref/Compile]) generates a (RefLink[CompiledFunction, paclet:ref/CompiledFunction]) object.

Compiled code does not handle numerical precision and local variables in the same way as ordinary Wolfram Language code.

If a compiled function cannot be evaluated with particular arguments using compiled code, ordinary Wolfram Language code is used instead.

Ordinary Wolfram Language code can be called from within compiled code. Results obtained from the Wolfram Language code are assumed to be approximate real numbers, unless specified otherwise by the third argument of (RefLink[Compile, paclet:ref/Compile]).

The number of times and the order in which objects are evaluated by (RefLink[Compile, paclet:ref/Compile]) may be different from ordinary Wolfram Language code.

(RefLink[Compile, paclet:ref/Compile]) has attribute (RefLink[HoldAll, paclet:ref/HoldAll]), and does not by default do any evaluation before compilation.

You can use (RefLink[Compile, paclet:ref/Compile])[…,(RefLink[Evaluate, paclet:ref/Evaluate])[expr]] to specify that expr should be evaluated symbolically before compilation.

The following options can be given:

OpenersPrimaryExamplesSection(Spacer1)Examples  (13)

OpenersExampleSection0(Spacer1)Basic Examples  (1)

Compile the function (RefLink[Sin, paclet:ref/Sin])[x]+x^2-1/(1-x) for machine real x:

cf = Compile[{{x, _Real}}, Sin[x] + x^2 - 1/(1+x)]

The (RefLink[CompiledFunction, paclet:ref/CompiledFunction]) evaluates with machine numbers:

cf[Pi]

Plot the compiled function:

Plot[cf[x],{x,-1,1}]

OpenersExampleSection1(Spacer1)Scope  (1)

Compile the function to take Newton iterations for (z^3)-1 and identify the nearest root:

newt = Compile[{{z,_Complex},{n,_Integer}}, Module[{zn = z},
Do[zn = (2 zn +1/zn^2)/3,{n}];If[Re[zn]>0,1,If[Im[zn]>0,2,3]]]]

Plot the basins of attraction for the three roots:

ArrayPlot[Table[newt[x+I y,25],{y,-1,1,2./199},{x,-1,1,2./199}]]

OpenersExampleSection2(Spacer1)Options  (9)

OpenersExampleSubsection0(Spacer1)CompilationOptions  (1)

The default setting of (RefLink[Automatic, paclet:ref/Automatic]) generates more efficient code by avoiding computing the same result more than once:

Compile[ {{x}},x^2+Sin[x^2]]

When the optimization level is reduced, less efficient code is generated:

Compile[ {{x}},x^2+Sin[x^2],CompilationOptions->{"ExpressionOptimization"->False}]

OpenersExampleSubsection1(Spacer1)CompilationTarget  (2)

This generates C code and links it back in for execution:

c=Compile[ {{x}},x^2+Sin[x^2],CompilationTarget->"C"];
c[ 10.5]

This is a larger example that demonstrates the speed advantages of C code generation:

c=Compile[ {{x,_Real},{n,_Integer}},
	Module[ {sum, inc},sum=1.0;inc=1.0;Do[inc=inc*x/i;sum=sum+inc,{i,n}];sum],CompilationTarget->"C"];
c[1.5, 10000000]//AbsoluteTiming

The default operation runs more slowly:

cNormal=Compile[ {{x,_Real},{n,_Integer}},
	Module[ {sum, inc},sum=1.0;inc=1.0;Do[inc=inc*x/i;sum=sum+inc,{i,n}];sum]];
cNormal[1.5, 10000000]//AbsoluteTiming

OpenersExampleSubsection2(Spacer1)Parallelization  (2)

Listable compiled functions can execute in parallel using threads:

cP=Compile[{{x}},
Module[{sum=1.0,inc=1.0},Do[inc=inc*x/i;sum=sum+inc,{i,10000}];sum],
RuntimeAttributes->{Listable},Parallelization->True];
arg=Range[ -50.,50, 0.02];
cP[arg];//AbsoluteTiming

This shows the operation running sequentially:

cS=Compile[{{x}},
Module[{sum=1.0,inc=1.0},Do[inc=inc*x/i;sum=sum+inc,{i,10000}];sum],
RuntimeAttributes->{Listable},Parallelization->False];
cS[arg];//AbsoluteTiming

Typically, (RefLink[$ProcessorCount, paclet:ref/$ProcessorCount]) is used to determine how many threads to be used:

$ProcessorCount

You can combine parallel operations with C code generation to get even faster operation:

cP1=Compile[{{x}},
Module[{sum=1.0,inc=1.0},Do[inc=inc*x/i;sum=sum+inc,{i,10000}];sum],
RuntimeAttributes->{Listable},Parallelization->True,CompilationTarget->"C"];
arg=Range[ -50.,50, 0.02];
cP1[arg];//AbsoluteTiming

OpenersExampleSubsection3(Spacer1)RuntimeAttributes  (3)

This creates a listable compiled function:

cListable=Compile[{x},x^2,RuntimeAttributes->{Listable}]

It operates on a single input in normal fashion:

cListable[ 10.1]

When the arguments include a list that does not match the input specification, it threads over that argument:

cListable[ {-5,0,5}]

If there is a branch, listability needs a function to be defined, as shown below using (RefLink[Function, paclet:ref/Function]):

arg=Range[1.,1000000];
fFun=Function[x,If[x>0,x^2,x^4],{Listable}];
fFun[arg];//AbsoluteTiming

A listable compiled function is equivalent but executes faster:

cFun=Compile[{x},If[x>0,x^2,x^4],RuntimeAttributes->{Listable}];
cFun[arg];//AbsoluteTiming

A listable compiled function can run in parallel, giving an acceleration on multicore machines:

cPFun=Compile[{x},If[x>0,x^2,x^4],RuntimeAttributes->{Listable},Parallelization->True];
cPFun[arg];//AbsoluteTiming

Using the listable attribute is typically faster than invoking (RefLink[CompiledFunction, paclet:ref/CompiledFunction]) many times:

newt = Compile[{{z,_Complex},{n,_Integer}}, Module[{zn = z},
Do[zn = (2 zn +1/zn^2)/3,{n}];If[Re[zn]>0,1,If[Im[zn]>0,2,3]]], RuntimeAttributes->Listable];

AbsoluteTiming[nt = Table[newt[x+I y,25],{y,-1,1,2./399},{x,-1,1,2./399}];]

AbsoluteTiming[nl = newt[Table[x+I y,{y,-1,1,2./399},{x,-1,1,2./399}], 25];]

Using parallelization can give an even greater speedup:

newtp = Compile[{{z,_Complex},{n,_Integer}}, Module[{zn = z},
Do[zn = (2 zn +1/zn^2)/3,{n}];If[Re[zn]>0,1,If[Im[zn]>0,2,3]]], RuntimeAttributes->Listable, Parallelization->True];

AbsoluteTiming[np = newtp[Table[x+I y,{y,-1,1,2./399},{x,-1,1,2./399}], 25];]

The results are identical:

SameQ[nt, nl, np]

A detailed plot of the basins of attraction for Newton's method for (z^3)-1:

ArrayPlot[np]

OpenersExampleSubsection4(Spacer1)RuntimeOptions  (1)

Typically, integer arithmetic overflow is caught and the computation switches to use bignums:

fi1 = Compile[{{n, _Integer}}, Module[{s = 1}, Do[s =(2*s+i),{i,n}];s]];
fi1[100]

Turning off overflow checking makes for faster execution, but the result can be incorrect:

fi2 = Compile[{{n, _Integer}}, Module[{s = 1}, Do[s =(2*s+i),{i,n}];s],RuntimeOptions->"Speed"];
fi2[100]

OpenersExampleSection3(Spacer1)Possible Issues  (1)

With the default setting for (RefLink[RuntimeOptions, paclet:ref/RuntimeOptions]) intermediate overflow may be missed:

fs = Compile[{{x, _Real}}, Boole[1/x>0]]; fs[0]

With the "Quality" setting, intermediate terms are tested for overflow:

fq = Compile[{{x, _Real}}, Boole[1/x>0], RuntimeOptions->"Quality"]; fq[0]

OpenersExampleSection4(Spacer1)Neat Examples  (1)

Perlin noise is a common algorithm used to generate procedural textures:

dot=With[{grad={{1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0},{1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1},{0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}}},
Compile[{{gradIdx,_Integer},{x,_Real},{y,_Real},{z,_Real}},
grad[[gradIdx+1]][[1]]*x+grad[[gradIdx+1]][[2]]*y+grad[[gradIdx+1]][[3]]*z
]
];
fade=Compile[{{t,_Real}},t*t*t*(t*(t*6.0-15.0)+10.0)];
lerp=Compile[{{x,_Real},{y,_Real},{t,_Real}},(1.0-t)*x+t*y];
signedNoise=With[{permutations=Join[(permutations=RandomSample[Range[0,255]]),permutations]},
Compile[{{x0,_Real},{y0,_Real},{z0,_Real}},
Module[{x, y, z,ix,iy,iz, g000,g001, g010, g011, g100, g101, g110, g111,n000,n100,n010,n110,n001,n101,n011,n111, u, v, w, nx00, nx01,nx10,nx11,nxy0,nxy1,nxyz},
ix=IntegerPart[x0];
iy=IntegerPart[y0];
iz=IntegerPart[z0];

x =x0- ix;
y =y0- iy;
z =z0- iz;

ix=Mod[ix,255]+1;
iy=Mod[iy,255]+1;
iz=Mod[iz,255]+1;

g000 = Mod[permutations[[ix+permutations[[iy+permutations[[iz]]]]]],12];
g001 = Mod[permutations[[ix+permutations[[iy+permutations[[iz+1]]]]]],12];
g010 = Mod[permutations[[ix+permutations[[iy+1+ permutations[[iz]]]]]],12];
g011 = Mod[permutations[[ix+permutations[[iy+1+permutations[[iz+1]]]]]],12];
g100 = Mod[permutations[[ix+1+permutations[[iy+permutations[[iz]]]]]],12];
g101 = Mod[permutations[[ix+1+permutations[[iy+permutations[[iz+1]]]]]],12];
g110 = Mod[permutations[[ix+1+permutations[[iy+1+permutations[[iz]]]]]],12];
g111 = Mod[permutations[[ix+1+permutations[[iy+1+permutations[[iz+1]]]]]],12];

n000=dot[g000,x,y,z];
n100=dot[g100,x-1,y,z];
n010=dot[g010,x,y-1,z];
n110=dot[g110,x-1,y-1,z];
n001=dot[g001,x,y,z-1];
n101=dot[g101,x-1,y,z-1];
n011=dot[g011,x,y-1,z-1];
n111=dot[g111,x-1,y-1,z-1];

u = fade[x];
v=fade[y];
w=fade[z];

nx00=lerp[n000,n100,u];
nx01=lerp[n001,n101,u];
nx10=lerp[n010,n110,u];
nx11=lerp[n011,n111,u];

nxy0=lerp[nx00,nx10,v];
nxy1=lerp[nx01,nx11,v];

nxyz=lerp[nxy0,nxy1,w];

nxyz
],
CompilationOptions->{"InlineExternalDefinitions"->True},"CompilationTarget"->"WVM"
]
];
classicPerlin=
With[{octaves=8},Compile[{{xIndex,_Integer},{yIndex,_Integer},{amplitude,_Real},{frequency,_Real},{gain,_Real},{lacunarity,_Real},{scale,_Real},{increment,_Real},{width,_Integer},{height,_Integer}},
Module[{noiseVal=0.0,x,y,z,freq=frequency,amp=amplitude},
x=xIndex*frequency/scale;
y=yIndex*frequency/scale;
z=1.0*frequency/scale;
Do[
noiseVal+=signedNoise[x*freq,y*freq,z*freq]*amp;
freq*=lacunarity;
amp*=gain,
{octaves}
];
Min[Max[noiseVal,0.0],1.0]
],CompilationOptions->{"InlineExternalDefinitions"->True}
]
];
createImage[img_, r_,g_,b_]:=Image[{r*img,g*img,b*img},Interleaving->False]
perlin[width_Integer,height_Integer]:=Table[classicPerlin[ii,jj,amplitude,frequency,gain,lacunarity,scale,increment,width,height],{ii,0,width},{jj,0,height}];

This defines the parameters to the Perlin noise function and uses the Perlin function to generate a landscape procedural texture:

amplitude=0.5;
frequency=1.0;
gain=0.5;
lacunarity=2.0;
increment=7.0;
scale=35.0;
ReliefImage[perlin[256,256]]

The same noise function, with different parameters and color set, can simulate wood grain:

amplitude=0.5;
frequency=1.0;
gain=0.5;
lacunarity=0.5;
scale=50.0;
increment=5.0;
data=20.0*perlin[256,256];
data=data-Map[IntegerPart,data,Infinity];
img=createImage[data,1.0,0.5,0.0]

You can apply textures to 3D objects:

ParametricPlot3D[{(2+Cos[v])Cos[u],(2+Cos[v])Sin[u],Sin[v]},{u,0,2Pi},{v,0,2Pi},Mesh->None,TextureCoordinateFunction->({#1,#2}&),PlotStyle->Texture[img],Boxed->False,Axes->None]

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[CompiledFunction, paclet:ref/CompiledFunction])  ▪  (RefLink[CompilationOptions, paclet:ref/CompilationOptions])  ▪  (RefLink[CompilationTarget, paclet:ref/CompilationTarget])  ▪  (RefLink[Parallelization, paclet:ref/Parallelization])  ▪  (RefLink[RuntimeAttributes, paclet:ref/RuntimeAttributes])  ▪  (RefLink[RuntimeOptions, paclet:ref/RuntimeOptions])  ▪  (RefLink[Dispatch, paclet:ref/Dispatch])  ▪  (RefLink[Function, paclet:ref/Function])  ▪  (RefLink[InterpolatingFunction, paclet:ref/InterpolatingFunction])  ▪  (RefLink[CForm, paclet:ref/CForm])}})}})

({{DocumentationFooterIconsRelatedTutorial.png, ({{Tutorials}, {▪(RefLinkPlain[Generating C and Fortran Expressions, paclet:tutorial/GeneratingCAndFortranExpressions])}, {▪(RefLinkPlain[Compiling Wolfram Language Expressions, paclet:tutorial/CompilingWolframLanguageExpressions])}, {▪(RefLinkPlain[The Wolfram Language Compiler User Guide, paclet:Compile/tutorial/Overview])}, {▪(RefLinkPlain[C Code Generation User Guide, paclet:CCodeGenerator/tutorial/Overview])}})}})

({{DocumentationFooterIconsRelatedGuide.png, ({{Related Guides}, {▪(RefLinkPlain[Parallel Computing, paclet:guide/ParallelComputing])}, {▪(RefLinkPlain[Time Measurement & Optimization, paclet:guide/TimeMeasurementAndOptimization])}, {▪(RefLinkPlain[Calling External Programs, paclet:guide/CallingExternalPrograms])}, {▪(RefLinkPlain[Code Compilation, paclet:guide/CodeCompilation])}, {▪(RefLinkPlain[Tuning & Debugging, paclet:guide/TuningAndDebugging])}})}})

({{(Spacer1), ({{(Spacer1)Related Links}, {(WebLink[DocumentationFooterIconsRelatedLinks-EIWL.png(Spacer1)An Elementary Introduction to the Wolfram Language, https://www.wolfram.com/language/elementary-introduction/46-writing-good-code.html])(WebLink[: Writing Good Code, https://www.wolfram.com/language/elementary-introduction/46-writing-good-code.html])}, {(WebLink[DocumentationFooterIconsRelatedLinks-NKS.png(Spacer1)NKS|Online, http://www.wolframscience.com/nksonline/index/search.cgi?SearchIndex=Compile]) ((WebLink[A New Kind of Science, http://www.wolframscience.com/nksonline/]))}})}})