是否期望这种慢速WPF TextBlock性能?

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使用率,这可能是不值得的.