[英]Brushes.White slows graphics demo down
以下是WPF中Conway的“人生游戲”的一個(非常幼稚的)實現。 這只是一個演示...
xaml:
<Window x:Class="wpf_conway_life_2013_05_19.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="500" Width="500">
<Grid>
<Canvas Name="canvas"
Width="auto"
Height="auto"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
</Canvas>
</Grid>
</Window>
后面的代碼:
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<int, int, int> at = (x, y) =>
{
if (x < 0) x = 100 + x;
if (x >= 100) x = x % 100;
if (y < 0) y = 100 + y;
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 < 100; y++)
{
rectangles[x, y] = new Rectangle();
canvas.Children.Add(rectangles[x, y]);
}
canvas.SizeChanged += (s, e) =>
{
for (var x = 0; x < 100; x++)
{
for (var y = 0; y < 100; y++)
{
rectangles[x, y].Width = canvas.ActualWidth / 100;
rectangles[x, y].Height = canvas.ActualHeight / 100;
Canvas.SetLeft(rectangles[x, y], (canvas.ActualWidth / 100) * x);
Canvas.SetTop(rectangles[x, y], (canvas.ActualHeight / 100) * y);
}
}
};
Action macroStep = () =>
{
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 < 2) dataB[x, y] = 0;
if (neighbors == 3) dataB[x, y] = 1;
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();
}
}
}
看起來是這樣的:
如果我將new SolidColorBrush(new Color())
替換為Brushes.White
則程序運行會慢得多。 為什么?
我正在使用2010 Express在Windows 7 64位上進行測試。
因為new Color()
alpha值為零,這意味着WPF不必渲染它,因為它是完全透明的-另一方面,白色的alpha是255,這意味着它必須是完全純白色的。
使用Brushes.White
沒有什么特別的。
如果在macroStep事件處理程序之外定義自己的本地畫筆,然后凍結它,則其行為與使用Brushes.White完全相同。 如果不先凍結它,它將表現得非常差。
最好的性能是在每次調用macroStep之前(循環之前)創建一次畫筆,然后凍結它。 如果在最內部的循環中創建新的筆刷,則速度會大大降低。
另外,如果您增加了行為不佳代碼的計時器間隔,則實際上可以解決性能問題。 我的猜測是,每次完成渲染后,都會在后台線程上進行某種資源清理,這與筆刷的內部息息相關,但是由於您要轉身,它無法進行清理工作實在令人望而卻步。並在下一次迭代中使用畫筆。 為了演示這一點,我創建了一個畫筆池,並每次都使用不同的畫筆:
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或更大,您將獲得預期的性能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.