2013-07-04 33 views
0

我有一個簡單的過程,循環一組點數據並做線性插值來'填寫'數據,我想知道是否有人可以幫助給我的代碼提供一些性能提示,並顯示我可以優化的區域代碼,謝謝!線性互補,可以優化運行速度嗎?

這裏代碼:

static internal Point3D[] _data; 
    static internal Point3dTree _kd; 

    static internal int _interpolation_count = 0; 
    static internal int _iteration_count = 0; 
    static Dictionary<int, Point3D> Interpolated_Values = new Dictionary<int, Point3D>(); 

    static internal int _threasindex; 
    static internal double[] _threasholds = new double[] 
    { 
     0.5, 
     1.0, 
     1.5, 
     20.5 
    }; 

    static internal double Interpolate(double x, double x0, double x1, double y0, double y1) 
    { 
     if ((x1 - x0) == 0) 
      return (y0 + y1)/2; 

     return y0 + (x - x0) * (y1 - y0)/(x1 - x0); 
    } 

    static void Main(string[] args) 
    { 
     using (new ProceduralTimer("Loading data")) 
      _data = LasReader.GetData(@"C:\WindowsLP\SAMPLE_PROJECT\brisport2\area_cov.las"); 
     using (new ProceduralTimer("Bulding Kd tree")) 
      _kd = new Point3dTree(_data, false); 

     List<Point3D> InterpolatedData = _data.ToList(); 
     _data = null; 

     using (new ProceduralTimer("Processing")) 
     { 
      int i = 0; 
      var neighbours = new List<Point3D>(); 
      for (; i < InterpolatedData.Count; i++) 
      { 
      @rescan: 
       neighbours = _kd.NearestNeighbours(new KdTreeNode<Point3D>(InterpolatedData[i]), _threasholds[_threasindex % _threasholds.Length]); 

       if (neighbours.Count < 4 && _threasindex < _threasholds.Length) 
       { 
        _threasindex++; 
        _iteration_count++; 
        goto rescan; 
       } 
       else 
       { 
        if (neighbours.Count >= 4) 
        { 
         double[] xvalues = neighbours.Select(_ => _.X).ToArray(); 
         double[] yvalues = neighbours.Select(_ => _.Y).ToArray(); 
         double[] zvalues = neighbours.Select(_ => _.Z).ToArray(); 

         Point3D pt = new Point3D(); 
         pt.X = Math.Round(Interpolate(InterpolatedData[i].X, xvalues[0], xvalues[1], xvalues[2], xvalues[3]), 2); 
         pt.Y = Math.Round(Interpolate(InterpolatedData[i].Y, yvalues[0], yvalues[1], yvalues[2], yvalues[3]), 2); 
         pt.Z = Math.Round(Interpolate(InterpolatedData[i].Z, zvalues[0], zvalues[1], zvalues[2], zvalues[3]), 2); 

         Interpolated_Values[i] = pt; 

         _interpolation_count++; 
        } 

        _threasindex = 0; 
       } 
      } 
     } 
+1

這個問題可能是更適合於[代碼審查堆棧交易所(http://codereview.stackexchange.com/ )。 –

+0

根據Don Knuth的說法,「爲什麼你需要優化代碼?」,[過早優化是萬惡之源](http://en.wikiquote.org/wiki/) Donald_Knuth)。如果你做**需要優化代碼,你是否需要減少時間或空間的使用,並且對於其中一個,你準備增加多少以減少另一個? – Simon

+0

您可以將for循環轉換爲Parallel.ForEach方法。此外,您可以用do while循環替換goto以提高可讀性。 – user467384

回答

1

所有您所使用的語言特點是除了LINQ提取x和y z值相當低的水平。

double[] xvalues = neighbours.Select(_ => _.X).ToArray(); 
double[] yvalues = neighbours.Select(_ => _.Y).ToArray(); 
double[] zvalues = neighbours.Select(_ => _.Z).ToArray(); 

嘗試一次迭代通過neighbours收集提取的XYZ值:

List<double> xvalues = new List<double>(); 
List<double> yvalues = new List<double>(); 
List<double> zvalues = new List<double>(); 

foreach(var neighbour in neighbours) 
{ 
    xvalues.Add(neighbour.X); 
    yvalues.Add(neighbour.Y); 
    zvalues.Add(neighbour.Z); 
}