performance - 优化矢量化 Matlab 函数

标签 performance matlab optimization vectorization mex

当我运行探查器时,它告诉我最耗时的代码是函数vdist。它是一个将地球视为椭球体来测量地球上两点之间距离的程序。该代码看起来很标准,我不知道在哪里以及如何改进它。最初的评论说,它已经被矢量化。是否有其他语言的对应版本可以用作 MEX 文件。我想要的只是时间效率方面的提高。这是 Matlab FEX 代码的链接。

http://www.mathworks.com/matlabcentral/fileexchange/8607-vectorized-geodetic-distance-and-azimuth-on-the-wgs84-earth-ellipsoid/content/vdist.m

该函数是从循环内调用的 - (您可以在此处找到该函数,因为它是最耗时的行)

              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中,变量p0NV1仅出现在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/

相关文章:

performance - C++ 中的高效消息工厂和处理程序

c - 将 Matlab 函数转换为 C 函数

javascript - 提高页面性能,在服务器上保存 PHP 数组?

c++ - 优化:为什么 < 比 multiple 更昂贵!=

java - 如何提高 Field.set 的性能(可能使用 MethodHandles)?

matlab - 如何将函数应用于矩阵中的所有行?

c++ - MKL 库在 mex 文件和独立 C++ 中的行为不同

python - 我怎样才能让这个Python文件扫描得更快?

python - 质数和 - for 循环和大数

css - 手机绝对位置优化