Brushes.White减慢了图形演示速度

以下是Conway在WPF中的生命游戏的一个(非常天真)实现。 这只是一个演示……

XAML:

      

代码背后:

 using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; using System.Windows.Threading; namespace wpf_conway_life_2013_05_19 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var random = new Random(); var data = new int[100, 100]; var dataB = new int[100, 100]; Func at = (x, y) => { if (x = 100) x = x % 100; if (y = 100) y = y % 100; return data[x, y]; }; for (var x = 0; x < 100; x++) for (var y = 0; y < 100; y++) data[x, y] = random.Next(2); var rectangles = new Rectangle[100, 100]; for (var x = 0; x < 100; x++) for (var y = 0; y  { for (var x = 0; x < 100; x++) { for (var y = 0; y  { dataB = new int[100, 100]; for (var x = 0; x < 100; x++) { for (var y = 0; y < 100; y++) { var neighbors = 0; for (var i = -1; i <= 1; i++) for (var j = -1; j <= 1; j++) if (i == 0 && j == 0) continue; else neighbors += at(x + i, y + j); dataB[x, y] = data[x, y]; if (neighbors  3) dataB[x, y] = 0; rectangles[x, y].Fill = dataB[x, y] == 0 ? new SolidColorBrush(new Color()) : Brushes.Black; } } data = dataB; }; var timer = new DispatcherTimer(); timer.Tick += (s, e) => macroStep(); timer.Start(); } } } 

这是它的样子:

在此处输入图像描述

如果我用Brushes.White替换new SolidColorBrush(new Color()) ,程序运行得慢得多。 为什么?

我正在使用2010 Express在Windows 7 64位上进行测试。

因为new Color() alpha值为零,这意味着WPF不必渲染它,因为它是完全透明的 – 另一方面,白色的alpha是255,这意味着它是完全纯白色,必须渲染。

使用Brushes.White并没有什么特别之处。

如果在macroStep事件处理程序之外定义自己的本地画笔,然后将其冻结,它将与使用Brushes.White完全相同。 如果你不先冻结它,它会表现得更糟,更糟糕。

最好的性能是在每次调用macroStep之前,在循环之前创建一次刷子,然后将其冻结。 如果在最里面的循环内创建一个新画笔,这是一个显着的减速。

此外,如果您为计时不良的代码增加计时器的间隔,它实际上将解决性能问题。 我的猜测是,在每次完成渲染之后,在后台线程上会发生某种资源清理,这与刷子的内部结构有关,但由于你正在向右转,因此无法进行清理。并在下一次迭代中使用画笔。 为了certificate这一点,我创建了一个画笔池,每次使用不同的画笔:

 SolidColorBrush[] brushes = new SolidColorBrush[2]; for (int i = 0; i < brushes.Length; i++) { var brush = new SolidColorBrush(new Color()); brush.Freeze(); brushes[i] = brush; } int brushIx = 0; Action macroStep = () => { dataB = new int[100, 100]; var brush = brushes[brushIx++ % brushes.Length]; ... rectangles[x, y].Fill = dataB[x, y] == 0 ? brush : Brushes.Black; data = dataB; }; 

如果将画笔数设置为1,则会产生与使用Brushes.White相同的行为。 但如果将其设置为2或更高,您将获得预期的性能。