【发布时间】:2014-08-22 12:54:18
【问题描述】:
在我目前正在构建的一个程序中,为每个部分的跟踪存储了一系列数组。每条迹线由几个长度为 4096 的双精度数组组成。最多可以取 4 条迹线。
与此问题相关的数组是 Angle 数组,它是在 4096 个数据点上从 -90 度到 90 度内插值的数组(因此每个索引大约 0.044 度)。这个数组是在 C# 图表控件上绘制的,对照另一个厚度数据数组(也是 4096 点)。
我的图表控件还实现了 MouseMove 事件,该事件以 0.1 的间隔在图表的 X 轴(-90 到 90 度)上绘制一个光标。这个想法是,当用户将鼠标悬停在图表上时,图表顶部会弹出一个注释,显示鼠标悬停角度的厚度数据。
在后台,每次触发 MouseMove 事件,都会将光标在图表上的 X 位置放入一个函数中,以查找轨迹 1 的角度数组中最近角度的索引。这是搜索代码:
private int FindIndexOfAngle(double Angle)
{
int closestX = Array.BinarySearch(Traces[0].AngleArray, Angle);
if (closestX < 0)
{
closestX = ~closestX; // If closestX is bitwise complement of index of next highest value from binary search
double closestY = Traces[0].AngleArray[closestX] - Angle;
if (Traces[0].AngleArray[closestX - 1] - Angle < closestY) closestX = closestX - 1;
}
return closestX;
}
这里是图表 MouseMove 事件:
private void chartMain_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (chartMain.Series.Count > 0)
{
Point mousePoint = new Point(e.X, e.Y);
chartMain.ChartAreas[0].CursorX.SetCursorPixelPosition(mousePoint, true);
double pX = chartMain.ChartAreas[0].CursorX.Position;
if (pX >= -90 && pX <= 90)
{
chartMain.ChartAreas[0].CursorX.LineColor = Color.Red;
//if (pX == 90) chartMain.ChartAreas[0].CursorX.Position = 89.9;
RectangleAnnotation anno = new RectangleAnnotation();
int index = FindIndexOfAngle(pX);
anno.Text = pX.ToString("0.00") + " degrees";
if (Surface == Traces.Count)
{
for (int x = 0; x < Traces.Count; x++)
{
if (MeasurementSettings.PlotRawData) anno.Text += "\nTrace " + (x + 1) + ": " + Traces[x].ThicknessRaw[index].ToString("0.000 000") + " " + MainSettings.UnitsName;
else anno.Text += "\nTrace " + (x + 1) + ": " + Traces[x].ThicknessFiltered[index].ToString("0.000 000") + " " + MainSettings.UnitsName;
}
}
else
{
if (MeasurementSettings.PlotRawData) anno.Text += "\nTrace " + (Surface + 1) + ": " + Traces[Surface].ThicknessRaw[index].ToString("0.000 000") + " " + MainSettings.UnitsName;
else anno.Text += "\nTrace " + (Surface + 1) + ": " + Traces[Surface].ThicknessFiltered[index].ToString("0.000 000") + " " + MainSettings.UnitsName;
}
anno.Font = new Font("Microsoft Sans Serif", 12);
anno.AnchorX = 50;
anno.AnchorY = 14;
chartMain.Annotations.Clear();
chartMain.Annotations.Add(anno);
}
else chartMain.ChartAreas[0].CursorX.LineColor = Color.Transparent;
}
else chartMain.ChartAreas[0].CursorX.LineColor = Color.Transparent;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
然后,此索引用于显示屏幕上显示的每条迹线的厚度值(一次最多 4 个)。
当只有 1 个跟踪活动时,这非常有效。但一旦有 2 条或更多条迹线处于活动状态,它就会显着减慢。
如果不增加间隔,我怎样才能加快速度?
【问题讨论】:
-
估计数组中的位置可能会更快(因为您知道角度范围,以及从元素到元素的近似增量)并从那里进行线性搜索,而不是使用 Array.BinarySearch。
-
FindIndexOfAngle每次chartMain_MouseMove调用仅执行一次(即使您有 1000 条跟踪)。为什么您确定问题出在FindIndexOfAngle函数中? -
我还没有确定问题出在我的搜索中。我认为搜索可能非常有效,但是每次我在 1800 格内移动鼠标时都会触发所有搜索确实会带来性能问题。
-
与重绘(部分)图表相比,搜索数组似乎不太明显,恕我直言。