【问题标题】:Slow performance when searching large arrays搜索大型数组时性能下降
【发布时间】: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 格内移动鼠标时都会触发所有搜索确实会带来性能问题。
  • 与重绘(部分)图表相比,搜索数组似乎不太明显,恕我直言。

标签: c# arrays search charts


【解决方案1】:

经过一番搜索,我找到了为什么我的 MouseMove 更新这么慢。

我假设性能缓慢与搜索数组有关,但感谢 cmets 的 Chris,我反而调查了绘图方面,发现我不正确地使用 Line 的 SeriesChartType,我应该正在使用 FastLine。

来自 MSDN:

The FastLine chart type is a variation of the Line chart that significantly 
reduces the   drawing time of a series that contains a very large number of 
data points. Use this chart in situations where very large data sets are used
and rendering speed is critical.

Some charting features are omitted from the FastLine chart to improve performance. 
The features omitted include control of point level visual attributes, markers, 
data point labels, and shadows.

http://msdn.microsoft.com/en-us/library/dd489249.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-21
    • 2014-09-04
    • 2018-11-09
    • 2013-12-18
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    相关资源
    最近更新 更多