Ben*_*pke 18 c# wpf performance textblock
我正在做一些基准测试,以确定我是否可以将WPF用于新产品.然而,早期的表现结果令人失望.我做了一个快速的应用程序,它使用数据绑定每100毫秒在列表框内显示一堆随机文本,它占用了大约15%的CPU.所以我创建了另一个跳过数据绑定/数据模板方案的快速应用程序,除了每100毫秒更新一个ListBox内的10个TextBlocks之外什么都不做(实际产品不需要100毫秒更新,更像是500毫秒最大值,但是这是一个压力测试).我仍然看到大约5-10%的CPU使用率.为什么这么高?是因为所有的垃圾串吗?
这是不使用绑定的版本的XAML:
<Grid>
<ListBox x:Name="numericsListBox">
<ListBox.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="48"/>
<Setter Property="Width" Value="300"/>
</Style>
</ListBox.Resources>
<TextBlock/>
<TextBlock/>
<TextBlock/>
<TextBlock/>
<TextBlock/>
<TextBlock/>
<TextBlock/>
<TextBlock/>
<TextBlock/>
<TextBlock/>
</ListBox>
</Grid>
Run Code Online (Sandbox Code Playgroud)
这是背后的代码:
public partial class Window1 : Window
{
private int _count = 0;
public Window1()
{
InitializeComponent();
}
private void OnLoad(object sender, RoutedEventArgs e)
{
var t = new DispatcherTimer(TimeSpan.FromSeconds(0.1), DispatcherPriority.Normal, UpdateNumerics, Dispatcher);
t.Start();
}
private void UpdateNumerics(object sender, EventArgs e)
{
++_count;
foreach (object textBlock in numericsListBox.Items)
{
var t = textBlock as TextBlock;
if (t != null)
t.Text = _count.ToString();
}
}
}
Run Code Online (Sandbox Code Playgroud)
根据任务管理器消耗大约5-10%的CPU,或者高达其中一个核心的大约20%!有什么想法可以更好地快速呈现文本?
我的电脑:XP SP3,2.26 GHz Core 2 Duo,4 GB RAM,Intel 4500 HD集成显卡.这比我在实际产品中需要开发的硬件强一个数量级.
Ray*_*rns 41
这种缓慢的TextBlock性能是否正常?
没有.这种慢速的TextBlock性能绝对不正常.我的经验是TextBlocks比这快得多.
我使用您发布的代码运行了几个测试,将更新间隔保持为0.1秒,并改变了TextBlocks的硬件和数量.这是我发现的:
10 TextBlocks, 2.16GHz Core 2 Duo, Radeon 4100 GPU: CPU Usage "0%"
10 TextBlocks, 2.16GHz Core 2 Duo, Software rendering: CPU Usage 1%
100 TextBlocks, 2.16GHz Core 2 Duo, Radeon 4100 GPU: CPU Usage 8%
100 TextBlocks, 2.16GHz Core 2 Duo, Software rendering: CPU Usage 18%
10 TextBlocks, 200MHz Pentium Pro, Software rendering: CPU Usage 35%
10 TextBlocks, 200MHz Pentium Pro, No rendering: CPU Usage 7%
Run Code Online (Sandbox Code Playgroud)
这些测试中的每一个都表明WPF的速度大约是测量结果的10倍.如果您的代码非常简单,我怀疑您的GPU或DirectX驱动程序会出现奇怪的问题.
请注意,对于100个TextBlock测试,我必须进行三项更改:添加90个TextBlocks,将ItemsPanel设置为WrapPanel以获取列中的数据,并减少TextBlock宽度以使所有内容适合屏幕.
我对200MHz Pentium Pro的测试可能与您的嵌入式硬件最相关.如果您的应用程序每0.5秒更新10个TextBlock,您可以使用大约3%的CPU进行更新,并在200MHz CPU上重绘.
如果我想让它变得更快怎么办?
使用数据绑定TextBlocks列表非常方便,但WPF还提供了可在需要绝对最大性能时使用的低级机制.
WPF TextBlock实际上包含格式化文档而不仅仅是字符串,因此它是一个非常复杂的数据结构.编写自己的TrivialTextBlock控件非常简单,该控件具有字符串参数,只需使用继承的TextElement属性(如FontSize,FontWeight等)绘制它.这通常不会完成,因为TextBlock几乎可以用于所有目的.
另一个考虑因素是每次更改TextBlock中的文本时,WPF都会重新计算布局.与旧技术不同,WPF TextBlock的内容可以非常轻松地更改UI的布局.因此,每次更改时都必须重新测量并重新格式化文本.TrivialTextBlock通过固定控制尺寸从而避免布局通过,创建上述控制也可以加快速度.
第三个考虑因素是WPF的文本格式化程序具有高级排版功能,支持字距调整,双向文本,连字,unicode功能,自定义字体权重等.要在WPF中获得绝对最大性能,您可以完全绕过文本格式化程序并绘制文字作为一系列图像.这需要大约20行XAML和大约40行C#代码.
所有这些优化都是可能的,但在你的情况下我不会打扰它们:这样做可以节省仅3%的CPU使用率,这可能是不值得的.