我使用动态数据显示绘制动画图形 - 具有不断添加新点的图形(每秒约10次,每次10点)。问题是如果这些点形成的线段与绘图仪尺寸相比较大,则性能会下降。换句话说,我可以添加数千个点,但如果它们形成相对较小的线段,性能将会很好。但是如果我只添加几百个形成大线段的点(它们占据了所有绘图仪的区域),那么性能将非常差。
以下图片说明了这个问题。第一张图片只有几百个线段,我的机器性能很差。在第二张图片中,由于绘图仪的缩放,我只需添加两点使得其余点在绘图仪上占据一席之地。
机器的速度并不重要(我的是配备集成GPU的Pentium G3220,16 GB RAM,另一个是带有分立GeForce 640 GT的相对CPU) - 我可以添加更多点并且会降低您的机器。行为将是相同的 - 如果我添加两个"防御缩放"在绘图仪上点和使线段相对较小,性能会好得多。
以下代码 - 我如何获得这样的图片。在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)光栅化 - 线段在屏幕上占据的像素越多,性能就越差......但是老兄,我的机器上有几百行掉线但是最大设置上的孤岛危机并没有!可笑!
我知道以下方法可以解决这个问题:
你还能提供什么?