我在两个项目中看似相同的C#代码基准测试存在问题。
代码是绕组数算法的C#实现,用于确定某个点是否在多边形内。
列表是Vertexes的有序列表,其中包含Latitude&经度。当您从每个顶点绘制一条线时,按顺序追踪多边形,并且该方法确定该点是否在多边形内部。
以下是代码:
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;
}
}
以下是我在两个项目中使用的代码进行基准测试(我使用并发包,因为我并行处理,在&#34; *****&#34; ):
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());
在一个解决方案中,我返回的平均时间约为0.007毫秒,但在另一个解决方案中,它在0.014毫秒时约为两倍。
在两个解决方案中,我传递的是相同的数据集,其中List的顺序相同,整个方法(多次调用)按相同的顺序调用。
我的解决方案都在&#34; Debug&#34;中进行了比较。和&#34;发布&#34;,并且两者都与&#34;优化代码&#34;进行了比较。标志设置,在所有测试中具有相同的性能差异比率。
您是否可以建议我可以调整/调查的任何其他设置/代码问题,以找出性能差异的原因?此外,如果您需要更多信息,请告诉我,我会提供。
更新 我在两个项目上运行了Visual Studio性能分析。这是慢速版本:
http://i.imgur.com/kQamIUD.png
以下是快速版:
http://i.imgur.com/UaVNcaM.png
道歉,我无法直接超链接图片,我还没有10个声誉。
答案 0 :(得分:4)
在对性能进行基准测试时,不要使用 DateTime.Now
来跟踪已用时间。相反,使用System.Diagnostics.Stopwatch
类,它是为此目的而构建的,更加精确:
var stopwatch = Stopwatch.StartNew();
// Execute code
stopwatch.Stop();
long duration = stopwatch.ElapsedMilliseconds;
您还应该测量相同代码的多次执行,而不仅仅是单个代码。很短的执行时间很难准确测量。考虑运行您的代码一百万次并比较这些值。