我正在尝试学习一点Julia,在阅读了几个小时的手册之后,我写了下面这段代码: ie = 200;ez = zeros(ie + 1);hy = zeros(ie);fdtd1d (steps)= for n in 1:steps for i in 2:ie ez[i]+= (hy[i] - hy[i-1]) end ez[1]= sin(n/10)
ie = 200; ez = zeros(ie + 1); hy = zeros(ie); fdtd1d (steps)= for n in 1:steps for i in 2:ie ez[i]+= (hy[i] - hy[i-1]) end ez[1]= sin(n/10) for i in 1:ie hy[i]+= (ez[i+1]- ez[i]) end end @time fdtd1d(10000);
06001
我相信它在优化之下,因为它比相应的Mathematica版本要慢得多:
ie = 200; ez = ConstantArray[0., {ie + 1}]; hy = ConstantArray[0., {ie}]; fdtd1d = Compile[{{steps}}, Module[{ie = ie, ez = ez, hy = hy}, Do[ez[[2 ;; ie]] += (hy[[2 ;; ie]] - hy[[1 ;; ie - 1]]); ez[[1]] = Sin[n/10]; hy[[1 ;; ie]] += (ez[[2 ;; ie + 1]] - ez[[1 ;; ie]]), {n, steps}]; Sow@ez; Sow@hy]]; result = fdtd1d[10000]; // AbsoluteTiming
06003
那么,如何让fdtd1d的Julia版更快?
两件事情:第一次运行该函数时,时间将包括代码的编译时间.如果你想要与Mathematica中的编译函数进行比较,你应该运行两次函数并在第二次运行时运行.用你的代码我得到:
elapsed time: 1.156531976 seconds (447764964 bytes allocated)
第一次运行,包括编译时间和
elapsed time: 1.135681299 seconds (447520048 bytes allocated)
对于第二次运行时,您不需要编译.
第二件事,可以说更重要的是,你应该避免性能关键代码中的全局变量.这是the performance tips section of the manual的第一个提示.
以下是使用局部变量的相同代码:
function fdtd1d_local(steps, ie = 200) ez = zeros(ie + 1); hy = zeros(ie); for n in 1:steps for i in 2:ie ez[i]+= (hy[i] - hy[i-1]) end ez[1]= sin(n/10) for i in 1:ie hy[i]+= (ez[i+1]- ez[i]) end end return (ez, hy) end fdtd1d_local(10000) @time fdtd1d_local(10000);
要比较我的机器上的Mathematica代码
{0.094005, Null}
而@time对fdtd1d_local的结果是:
elapsed time: 0.015188926 seconds (4176 bytes allocated)
或者大约快6倍.全局变量产生很大的不同.