绘制动画图时性能会下降

时间:2016-07-01 12:41:42

标签: c# wpf performance dynamic-data-display

我使用动态数据显示绘制动画图形 - 具有不断添加新点的图形(每秒约10次,每次10点)。问题是如果这些点形成的线段与绘图仪尺寸相比较大,则性能会下降。换句话说,我可以添加数千个点,但如果它们形成相对较小的线段,性能将会很好。但是如果我只添加几百个形成大线段的点(它们占据了所有绘图仪的区域),那么性能将非常差。

以下图片说明了这个问题。第一张图片只有几百个线段,我的机器性能很差。在第二张图片中,由于绘图仪的缩放,我只需添加两点使得其余点在绘图仪上占据一席之地。

机器的速度并不重要(我的是配备集成GPU的Pentium G3220,16 GB RAM,另一个是带有分立GeForce 640 GT的相对CPU) - 我可以添加更多点并且会降低您的机器。行为将是相同的 - 如果我添加两个"防御缩放"在绘图仪上点和使线段相对较小,性能会好得多。

enter image description here enter image description here

以下代码 - 我如何获得这样的图片。在MainWindow()中添加两个点以获取第一张图片,并取消注释以获取第二张图片。这只是一个平面WPF应用程序,所有代码都在一个文件中 - 在MainWindow"代码背后":

public partial class MainWindow : Window
{
    readonly DispatcherTimer _timer = new DispatcherTimer();

    int _counter = 0;
    int _batchSize= 10;

    RingArray<Point> _data = new RingArray<Point>(2000);

    EnumerableDataSource<Point> _ds;


    public MainWindow()
    {
        InitializeComponent();


        _ds = new EnumerableDataSource<Point>(_data);
        _ds.SetXMapping(d => d.X);
        _ds.SetYMapping(d => d.Y);

        LineGraph chart = plotter.AddLineGraph(_ds, Colors.Blue, 2.0);

        //_data.Add(
        //        new Point
        //        {
        //            X = -1,
        //            Y = 200
        //        });

        //_data.Add(
        //    new Point
        //    {
        //        X = -0.5,
        //        Y = -200
        //    });

        _timer.Tick += OnTimerTick;
        _timer.Interval = TimeSpan.FromMilliseconds(100);
        _timer.Start();
    }

    void OnTimerTick(object sender, EventArgs e)
    {
        _data.AddMany(
            Enumerable.Range(0, _batchSize)
            .Select(v =>
                {
                    // I don't use the "v" here - the "_counter" is enough.

                    var p = new Point
                    {
                        X = (double)_counter,
                        Y = (double)(_counter % 2 == 0 ? 0 : 1)
                    };

                    _counter++;

                    return p;
                }));
    }
}

public class Point
{
    public double X { get; set; }
    public double Y { get; set; }
}

我是否将EnumerableDataSource或ObservableDataSource与AppendAsync,Add或AddMany一起使用并不重要 - 它的行为完全相同:性能仅取决于相对于屏幕大小(或绘图仪大小)的线段大小。 问题肯定在1)WPF渲染系统和2)光栅化领域。

1)糟糕的WPF渲染系统https://jeremiahmorrill.wordpress.com/2011/02/14/a-critical-deep-dive-into-the-wpf-rendering-system/

2)光栅化 - 线段在屏幕上占据的像素越多,性能就越差......但是老兄,我的机器上有几百行掉线但是最大设置上的孤岛危机并没有!可笑!

我知道以下方法可以解决这个问题:

  1. 减小绘图仪的大小(但在我的情况下,它必须尽可能大,因为它是用户界面的主要部分,专用于监控目的);
  2. 减少线段的大小(不是我的情况,因为数据必须按原样显示);
  3. 对数据应用过滤器,例如仅绘制每个第十个点而不是每个第一个点 - 已经完成但是它的应用程序有限(我的图表看起来太过苛刻);
  4. 你还能提供什么?

0 个答案:

没有答案