19

我正在做一些基准测试以确定我是否可以将 WPF 用于新产品。然而,早期的业绩结果令人失望。我制作了一个快速应用程序,它使用数据绑定每 100 毫秒在列表框中显示一堆随机文本,它占用了大约 15% 的 CPU。所以我制作了另一个快速应用程序,它跳过了数据绑定/数据模板方案,除了每 100 毫秒更新一次 ListBox 内的 10 个 TextBlock 之外什么都不做(实际产品不需要 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>

这是后面的代码:

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();
        }
    }
}

根据任务管理器,这会消耗约 5-10% 的 CPU,或高达其中一个内核的 20%!关于快速呈现文本的更好方法的任何想法?

我的电脑:XP SP3、2.26 GHz Core 2 Duo、4 GB RAM、Intel 4500 HD 集成显卡。这比我在实际产品中需要开发的硬件要强大一个数量级。

4

3 回答 3

43

这种缓慢的 TextBlock 性能正常吗?

不,这么慢的 TextBlock 性能绝对不正常。我的经验是 TextBlocks 比这快得多。

我使用您发布的代码运行了几个测试,将更新间隔设置为 0.1 秒并改变硬件和 TextBlock 的数量。这是我发现的:

 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%

这些测试中的每一项都表明 WPF 的速度大约是您的测量结果的 10 倍。如果你的代码看起来很简单,我怀疑你的 GPU 或 DirectX 驱动程序有一些奇怪的地方。

请注意,对于 100 个 TextBlock 测试,我必须进行三项更改:添加 90 个 TextBlock,将 ItemsPanel 设置为 WrapPanel 以获取列中的数据,并减小 TextBlock 宽度以使所有内容都适合屏幕。

我在 200MHz Pentium Pro 上的测试可能与您的嵌入式硬件最相关。如果您的应用程序每 0.5 秒更新 10 个 TextBlock,您可以预期在 200MHz CPU 上使用大约3% 的 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 使用率可能不值得。

于 2010-03-18T20:11:52.680 回答
4

就性能而言,在 WPF 中有很多可以做错的地方。很多人在开发应用程序时将其视为 win 表单应用程序、html 网页或一些混合攻击,因此对 WPF 有很多不好的评价。

我了解您正在尝试进行性能测试以查看 WPF 是否适用于您的平台,并且可以在以下链接中找到如何让您的 WPF 应用程序控件针对您期望的负载类型执行的一个很好的示例。

http://msdn.microsoft.com/en-us/magazine/dd483292.aspx

Petzold 将指导您完成优化项目控件的过程,以针对 UI 上显示的数据负载进行最佳渲染。

为了进行公平的测试,我将编写一个示例应用程序来处理您将要处理的数据示例,然后测试该代码的性能。可以应用大量优化来使 WPF 应用程序尖叫并使用更少的 CPU,但它们都取决于您的应用程序以及它如何表示您的数据。

希望这可以帮助。

于 2010-03-17T21:15:39.030 回答
3

如果您确定您的部署硬件非常好,我只会将 WPF 用于新产品。实际上,我认为专用显卡是最低要求。

我的团队为一个针对 Atom 处理器平台的项目选择了 WPF,因为集成的 GMA 500 图形声称 WPF 渲染第 2 层。但是,由于某种原因,GMA 500 的性能非常慢,我们关闭了硬件渲染以获得更好的性能。即便如此,Atom 平台的性能也不足以提供合理的性能。如果上网本或英特尔凌动的任何产品是您的客户群的一部分,我建议不要使用 WPF。

这是我在 GMA 500 上对 WPF 的性能提出的问题的链接。

正如 Rob Perkins 建议的那样,使用 Silverlight 4 可能会更好,以获得更好的性能。

祝你好运!

于 2011-02-01T19:14:59.023 回答