2015-05-18 1 views
1

У меня есть проблема с, по-видимому, идентичным бенчмаркингом кода C# по-разному в двух проектах.Идентичный метод в двух проектах, имеющих разные характеристики

Этот код является реализацией C# алгоритма числа обмоток, чтобы выяснить, находится ли точка внутри многоугольника.

Список - это упорядоченный список вершин, имеющих широту & Долгота. Когда вы рисуете линию из каждой вершины, по порядку вы трассируете многоугольник, и метод определяет, находится ли точка внутри многоугольника.

Вот код:

public static bool IsPointInPolygon(List<Vertex> polygon, Vertex point) 
{ 
    int wn = 0; 
    for (int i = 0; i < (polygon.Count - 1); i++) 
    { 
     if (polygon[i].Latitude <= point.Latitude) 
     { 
      if (polygon[i + 1].Latitude > point.Latitude) 
      { 
       if (IsLeft(polygon[i], polygon[i + 1], point) > 0) 
        wn++; 
      } 
     } 
     else 
     { 
      if (polygon[i + 1].Latitude <= point.Latitude) 
      { 
       if (IsLeft(polygon[i], polygon[i + 1], point) < 0) 
        wn--; 
      } 
     } 
    } 
    return wn != 0; 
} 

private static double IsLeft(Vertex lineStart, Vertex lineEnd, Vertex point) 
{ 
    return ((lineEnd.Longitude - lineStart.Longitude) * (point.Latitude - lineStart.Latitude) 
     - (point.Longitude - lineStart.Longitude) * (lineEnd.Latitude - lineStart.Latitude)); 
} 

Вот мой Vertex класс:

public class Vertex 
{ 
    public double Latitude { get; set; } 
    public double Longitude { get; set; } 
    public int Order { get; set; } 

    public Vertex(double latitude, double longitude) 
    { 
     this.Latitude = latitude; 
     this.Longitude = longitude; 
    } 

    public Vertex(double latitude, double longitude, int order) 
    { 
     this.Latitude = latitude; 
     this.Longitude = longitude; 
     this.Order = order; 
    } 
} 

Вот код, я использую в обоих проектах в тесте (я использую параллельную сумку, потому что Я обрабатываю параллельно, внутри «*****»):

System.Collections.Concurrent.ConcurrentBag<double> times = new System.Collections.Concurrent.ConcurrentBag<double>(); 
// ***** 
// ***** 
var start = DateTime.Now; 
bool isPointInPoly = IsPointInPolygon(poly, point); // where poly is a List<Vertex> and point is a Vertex 
var end = DateTime.Now; 
times.Add((end - start).TotalMilliseconds); 
// ***** 
// ***** 
Debug.WriteLine(times.Average()); 

В одном решении среднее время I get return составляет приблизительно 0,007 мс, а в другом - примерно в два раза, что при 0,014 мс.

В обоих решениях я передаю идентичный набор данных, причем оба списка находятся в одном порядке, а весь метод (который называется много раз) вызывается в том же порядке.

Оба моих решения были сопоставлены в «Debug» и «Release», и оба были сопоставлены с установленным флагом «Оптимизировать код» с тем же соотношением разницы производительности во всех тестах.

Можете ли вы предложить любые другие проблемы с настройками/кодом, которые я мог бы настроить/исследовать, чтобы узнать причину разницы в производительности? Кроме того, если вам нужна дополнительная информация, сообщите мне, и я предоставлю ее.

Обновление: Я провел анализ производительности Visual Studio для обоих проектов. Вот медленная версия:

http://i.imgur.com/kQamIUD.png

А вот быстрая версия:

http://i.imgur.com/UaVNcaM.png

Извиняюсь, что я не могу гиперссылке изображения непосредственно, я не имею 10 репутации еще ,

ответ

4

Когда вы оцениваете производительность, не используютDateTime.Now для отслеживания прошедшего времени. Вместо этого используйте System.Diagnostics.Stopwatch класс, который построен для этой цели, и гораздо более точным:

var stopwatch = Stopwatch.StartNew(); 

// Execute code 

stopwatch.Stop(); 
long duration = stopwatch.ElapsedMilliseconds; 

Вы должны также измерить много исполнений одного и того же кода, а не только одного. Очень короткое время выполнения трудно точно измерить. Рассмотрите возможность запуска кода в миллион раз и сравните эти значения.

+0

Спасибо, что ответили Мариус. Я изменил таймер на это, но результат идентичен.Кроме того, я очень приблизил время работы 5000 * 2350, которое составляет чуть менее 12 миллионов раз, причем время составляет около 20 секунд в одном проекте и 40 секунд в другом. Кроме того, разница в производительности очевидна при работе по всему набору данных, поэтому я не думаю, что проблема связана с самим таймером. –

Смежные вопросы