当我运行探查器时,它告诉我最耗时的代码是函数vdist
。它是一个将地球视为椭球体来测量地球上两点之间距离的程序。该代码看起来很标准,我不知道在哪里以及如何改进它。最初的评论说,它已经被矢量化。是否有其他语言的对应版本可以用作 MEX 文件。我想要的只是时间效率方面的提高。这是 Matlab FEX 代码的链接。
该函数是从循环内调用的 - (您可以在此处找到该函数,因为它是最耗时的行)
109 for i=1:polySize
110 % find the two vectors needed
11755 111 if i~=1
0.02 11503 112 if i<polySize
0.02 11251 113 p0=Polygon(i,:); p1=Polygon(i-1,:); p2=Polygon(i+1,:);
252 114 else
252 115 p0=Polygon(i,:); p1=Polygon(i-1,:); p2=Polygon(1,:); %special case for i=polySize
252 116 end
252 117 else
252 118 p0=Polygon(i,:); p1=Polygon(polySize,:); p2=Polygon(i+1,:); %special case for i=1
252 119 end
0.02 11755 120 Vector1=(p0-p1); Vector2=(p0-p2);
0.06 11755 121 if ~(isequal(Vector1,Vector2) || isequal(Vector1,ZeroVec) || isequal(Vector2,ZeroVec));
122 %determine normals and normalise and
0.17 11755 123 NV1=rotateVector(Vector1, pi./2); NV2=rotateVector(Vector2, -pi./2);
0.21 11755 124 NormV1=normaliseVector(NV1); NormV2=normaliseVector(NV2);
125 %determine rotation by means of the atan2 (because sign matters!)
11755 126 totalRotation = vectorAngle(NormV2, NormV1); % Bestimme den Winkel totalRotation zwischen den normierten Vektoren
11755 127 if totalRotation<10
11755 128 totalRotation=totalRotation*50;
11755 129 end
0.01 11755 130 for res=1:6
0.07 70530 131 U_neu=p0+NV1;
17.01 70530 132 [pos,a12] = vdist(p0(:,2),p0(:,1),U_neu(:,2),U_neu(:,1));
0.02 70530 133 a12=a12+1/6.*res*totalRotation;
70530 134 ddist=1852*safety_distance;
4.88 70530 135 [lat2,lon2] = vreckon(p0(:,2),p0(:,1),ddist, a12);
0.15 70530 136 extendedPoly(f,:)=[lon2,lat2];f=f+1;
< 0.01 70530 137 end
11755 138 end
11755 139 end
最佳答案
无论我多么努力地研究已发布的代码,我都不明白为什么要在循环内调用 vdist
。
当我尝试优化循环内的代码块时,我寻找的其中一件事是不变的语句,即每次调用时都是相同的,因此可以将其从循环中取出.
看着
130 for res=1:6
131 U_neu=p0+NV1;
132 [pos,a12] = vdist(p0(:,2),p0(:,1),U_neu(:,2),U_neu(:,1));
133 a12=a12+1/6.*res*totalRotation;
134 ddist=1852*safety_distance;
135 [lat2,lon2] = vreckon(p0(:,2),p0(:,1),ddist, a12);
136 extendedPoly(f,:)=[lon2,lat2];f=f+1;
137 end
我明白了
- 在l131中,变量
p0
、NV1
仅出现在rhs上,并且它们仅出现在循环内其他地方的rhs上,因此该语句是循环不变的并且可以从循环中提出;也许只节省一点时间; - 再次在 l134 中,我看到另一个循环不变语句,可以再次将其从循环中取出,以节省一点时间;
- 但后来我开始非常仔细地观察,我不明白为什么调用
vdist
的 l132 也在循环内部。该赋值的右侧值均未在循环中修改(U_neu
除外,但我已将其移出循环)。
整理剩下的部分,这就是我最终得到的结果:
U_neu=p0+NV1;
[pos,a12] = vdist(p0(:,2),p0(:,1),U_neu(:,2),U_neu(:,1));
ddist=1852*safety_distance;
for res=1:6
extendedPoly(f,:) = vreckon(p0(:,2),p0(:,1),ddist, a12+1/6.*res*totalRotation);
f=f+1;
end
关于performance - 优化矢量化 Matlab 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13070637/