Compile
更多信息和选项
- 由 Compile 处理的类型是:
-
_Integer 机器整数 _Real 机器精度的近似实数(缺省) _Complex 机器精度近似复数 True | False 逻辑变量 - 作为经过编译的函数的输入给出的嵌套列表必须是全数值数组.
- Compile 处理数值函数、矩阵运算、程序式编程结构、列表操作函数以及函数式编程结构等等.
- Compile 生成 CompiledFunction 对象.
- 经过编译的代码处理数值精度和局部变量的方式与普通的 Wolfram 语言代码不同.
- 如果不能用经过编译的代码对有特殊参数的经过编译的函数求值,则使用普通的 Wolfram 语言代码代替.
- 普通 Wolfram 语言代码可以从经过编译的代码内部调用. 由 Wolfram 语言代码获得的结果假设是近似实数除非特别指明,否则由 Compile 的第三个参数指定.
- 用 Compile 计算的对象的次数和次序可能和普通的 Wolfram 语言代码不同.
- Compile 有属性 HoldAll,在默认情况下在编译前并不进行计算.
- 可以使用 Compile[…,Evaluate[expr]] 指定 expr 应当在编译前进行符号性计算.
- 可以给出下列选项:
-
CompilationOptions Automatic 编译过程的选项 CompilationTarget $CompilationTarget 代码产生的目标运行时间 Parallelization Automatic 经过编译的函数执行的并行控制 RuntimeAttributes {} 经过编译的函数的计算属性 RuntimeOptions Automatic 经过编译的函数的运行时间选项
范例
打开所有单元 关闭所有单元基本范例 (1)
对于机器实数 x,编译函数 Sin[x]+x^2-1/(1-x):
cf = Compile[{{x, _Real}}, Sin[x] + x ^ 2 - 1 / (1 + x)]CompiledFunction 用机器数进行计算:
cf[Pi]Plot[cf[x], {x, -1, 1}]范围 (1)
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]]]]ArrayPlot[Table[newt[x + I y, 25], {y, -1, 1, 2. / 199}, {x, -1, 1, 2. / 199}]]选项 (9)
CompilationOptions (1)
通过避免计算同样的结果超过一次,Automatic 的默认设置产生效率更高的代码:
Compile[ {{x}}, x ^ 2 + Sin[x ^ 2]]Compile[ {{x}}, x ^ 2 + Sin[x ^ 2], CompilationOptions -> {"ExpressionOptimization" -> False}]CompilationTarget (2)
c = Compile[ {{x}}, x ^ 2 + Sin[x ^ 2], CompilationTarget -> "C"];
c[ 10.5]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]//AbsoluteTimingcNormal = 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]//AbsoluteTimingParallelization (2)
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];//AbsoluteTimingcS = 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通常,$ProcessorCount 用来确定要使用多少线程:
$ProcessorCount用户可以使用 C 代码生成和并行操作结合起来,以获得更快的操作:
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];//AbsoluteTimingRuntimeAttributes (3)
cListable = Compile[{x}, x ^ 2, RuntimeAttributes -> {Listable}]cListable[ 10.1]cListable[ {-5, 0, 5}]如果存在一个分支,可列表性(listability)需要定义一个函数,如下所示,使用 Function:
arg = Range[1., 1000000];
fFun = Function[x, If[x > 0, x ^ 2, x ^ 4], {Listable}];
fFun[arg];//AbsoluteTimingcFun = Compile[{x}, If[x > 0, x ^ 2, x ^ 4], RuntimeAttributes -> {Listable}];
cFun[arg];//AbsoluteTimingcPFun = Compile[{x}, If[x > 0, x ^ 2, x ^ 4], RuntimeAttributes -> {Listable}, Parallelization -> True];
cPFun[arg];//AbsoluteTiming使用可列表属性通常比多次调用 CompiledFunction 更快:
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];]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];]SameQ[nt, nl, np]ArrayPlot[np]RuntimeOptions (1)
可能存在的问题 (1)
在 RuntimeOptions 的默认设置下,可能会错过中间溢出:
fs = Compile[{{x, _Real}}, Boole[1 / x > 0]]; fs[0]fq = Compile[{{x, _Real}}, Boole[1 / x > 0], RuntimeOptions -> "Quality"]; fq[0]巧妙范例 (1)
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}];下面定义了 Perlin 噪声函数的参数,并且使用 Perlin 函数生成一个地形过程纹理:
amplitude = 0.5;
frequency = 1.0;
gain = 0.5;
lacunarity = 2.0;
increment = 7.0;
scale = 35.0;
ReliefImage[perlin[256, 256]]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]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]历史
1991年引入 (2.0) | 在以下年份被更新:1996 (3.0) ▪ 2010 (8.0)
文本
Wolfram Research (1991),Compile,Wolfram 语言函数,https://reference.wolfram.com/language/ref/Compile.html (更新于 2010 年).
CMS
Wolfram 语言. 1991. "Compile." Wolfram 语言与系统参考资料中心. Wolfram Research. 最新版本 2010. https://reference.wolfram.com/language/ref/Compile.html.
APA
Wolfram 语言. (1991). Compile. Wolfram 语言与系统参考资料中心. 追溯自 https://reference.wolfram.com/language/ref/Compile.html 年
BibTeX
@misc{reference.wolfram_2026_compile, author="Wolfram Research", title="{Compile}", year="2010", howpublished="\url{https://reference.wolfram.com/language/ref/Compile.html}", note=[Accessed: 14-September-2026]}
BibLaTeX
@online{reference.wolfram_2026_compile, organization={Wolfram Research}, title={Compile}, year={2010}, url={https://reference.wolfram.com/language/ref/Compile.html}, note=[Accessed: 14-September-2026]}