zoukankan      html  css  js  c++  java
  • WPF性能优化经验总结和整理综合帖

    第一部分

    WPF性能优化一、Rendering Tier

    1. 根据硬件配置的不同,WPF采用不同的Rendering Tier做渲染。下列情况请特别注意,因为在这些情况下,即使是处于Rendering Tier 2的情况下也不会硬件加速。(不全,其余请查阅SDK)

    WPF性能优化二、布局和设计

    1.尽量多使用Canvas等简单的布局元素,少使用Grid或者StackPanel等复杂的,越复杂性能开销越大。

    2.建立逻辑树或者视觉树的时候,遵循Top-Down的原则。

    WPF性能优化三、图像

    1. 对Image做动画处理的时候(如调整大小等),可以使用这条语句RenderOptions.SetBitmapScalingMode(MyImage,BitmapScalingMode.LowQuality),以改善性能。

    2. 用TileBrush的时候,可以CachingHint。

    WPF性能优化四、对象行为

    1.访问CLR对象和CLR属性的效率会比访问DependencyObject/DependencyProperty高。注意这里指的是访问,不要和前面的绑定混淆了。但是,把属性注册为DependencyProperty会有很多的优点:比如继承、数据绑定和Style。

    WPF性能优化五、应用程序资源

    1. 在自定义控件,尽量不要在控件的ResourceDictionary定义资源,而应该放在Window或者Application级。因为放在控件中会使每个实例都保留一份资源的拷贝。

    2. 尽量使用Static Resources,但不能盲目使用。

    WPF性能优化六、文本

    1. 文字少的时候用TextBlock或者label,长的时候用FlowDocument.

    2. 使用元素TextFlow和TextBlock时,如果不需要TextFlow的某些特性,就应该考虑使用TextBlock,因为它的效率更高。

    3. 在TextFlow中使用UIElement(比如TextBlock)所需的代价要比使用TextElement(比如Run)的代价高.在FlowDocument中尽量避免使用TextBlock,要用Run替代。

    4. 在TextBlock中显式的使用Run命令比不使用Run命名的代码要高。
    5. 把Label(标签)元素的ContentProperty和一个字符串(String)绑定的效率要比把字符串和TextBlock的Text属性绑定的效率低。因为Label在更新字符串是会丢弃原来的字符串,全部重新显示内容。如果字符串不需要更新,用Label就无所谓性能问题。

    6. 在TextBlock块使用HyperLinks时,把多个HyperLinks组合在一起效率会更高。

    7. 显示超链接的时候,尽量只在IsMouseOver为True的时候显示下划线,一直显示下划线的代码高很多

    8. 尽量不使用不必要的字符串连接。

    WPF性能优化七、数据绑定

    1.在使用数据绑定的过程中,如果绑定的数据源是一个CLR对象,属性也是一个CLR属性,那么在绑定的时候对象CLR对象所实现的机制不同,绑定的效率也不同。

    A、数据源是一个CLR对象,属性也是一个CLR属性。对象通过TypeDescriptor/PropertyChanged模式实现通知功能。此时绑定引擎用TypeDescriptor来反射源对象。效率最低。

    B、数据源是一个CLR对象,属性也是一个CLR属性。对象通过INotifyPropertyChanged实现通知功能。此时绑定引擎直接反射源对象。效率稍微提高。

    C、数据源是一个DependencyObject,而且属性是一个DependencyProperty。此时不需要反射,直接绑定。效率最高。

    2.当一个CLR对象很大时,比如有1000个属性时,尽量把这个对象分解成很多很小的CLR对象。比如分成1000个只有一个属性的CLR对象。

    3. 当我们在列表(比如ListBox)显示了一个CLR对象列表(比如List)时,如果想在修改List对象后,ListBox也动态的反映这种变化。此时,我们应该使用动态的ObservableCollection对象绑定。而不是直接的更新ItemSource。两者的区别在于直接更新ItemSource会使WPF抛弃ListBox已有的所有数据,然后全部重新从List加载。而使用ObservableCollection可以避免这种先全部删除再重载的过程,效率更高。

    4. 尽量绑定IList而不是IEnumerable到ItemsControl。

    WPF性能优化八、其它性能建议

    1. 如果需要修改元素的Opacity属性,最后修改一个Brush的属性,然后用这个Brush来填充元素。因为直接修改元素的Opacity会迫使系统创建一个临时的Surface

    2. 用NavigationWindow的时候,尽量Update the client area by object,而不是URI

    3. 尽量不要使用ScrollBarVisibility=Auto

    WPF性能优化一、Rendering Tier

    1. 根据硬件配置的不同,WPF采用不同的Rendering Tier做渲染。下列情况请特别注意,因为在这些情况下,即使是处于Rendering Tier 2的情况下也不会硬件加速。(不全,其余请查阅SDK)

    WPF性能优化二、布局和设计

    1.尽量多使用Canvas等简单的布局元素,少使用Grid或者StackPanel等复杂的,越复杂性能开销越大。

    2.建立逻辑树或者视觉树的时候,遵循Top-Down的原则。

    WPF性能优化三、图像

    1. 对Image做动画处理的时候(如调整大小等),可以使用这条语句RenderOptions.SetBitmapScalingMode(MyImage,BitmapScalingMode.LowQuality),以改善性能。

    2. 用TileBrush的时候,可以CachingHint。

    WPF性能优化四、对象行为

    1.访问CLR对象和CLR属性的效率会比访问DependencyObject/DependencyProperty高。注意这里指的是访问,不要和前面的绑定混淆了。但是,把属性注册为DependencyProperty会有很多的优点:比如继承、数据绑定和Style。

    WPF性能优化五、应用程序资源

    1. 在自定义控件,尽量不要在控件的ResourceDictionary定义资源,而应该放在Window或者Application级。因为放在控件中会使每个实例都保留一份资源的拷贝。

    2. 尽量使用Static Resources,但不能盲目使用。

    WPF性能优化六、文本

    1. 文字少的时候用TextBlock或者label,长的时候用FlowDocument.

    2. 使用元素TextFlow和TextBlock时,如果不需要TextFlow的某些特性,就应该考虑使用TextBlock,因为它的效率更高。

    3. 在TextFlow中使用UIElement(比如TextBlock)所需的代价要比使用TextElement(比如Run)的代价高.在FlowDocument中尽量避免使用TextBlock,要用Run替代。

    4. 在TextBlock中显式的使用Run命令比不使用Run命名的代码要高。
    5. 把Label(标签)元素的ContentProperty和一个字符串(String)绑定的效率要比把字符串和TextBlock的Text属性绑定的效率低。因为Label在更新字符串是会丢弃原来的字符串,全部重新显示内容。如果字符串不需要更新,用Label就无所谓性能问题。

    6. 在TextBlock块使用HyperLinks时,把多个HyperLinks组合在一起效率会更高。

    7. 显示超链接的时候,尽量只在IsMouseOver为True的时候显示下划线,一直显示下划线的代码高很多

    8. 尽量不使用不必要的字符串连接。

    WPF性能优化七、数据绑定

    1.在使用数据绑定的过程中,如果绑定的数据源是一个CLR对象,属性也是一个CLR属性,那么在绑定的时候对象CLR对象所实现的机制不同,绑定的效率也不同。

    A、数据源是一个CLR对象,属性也是一个CLR属性。对象通过TypeDescriptor/PropertyChanged模式实现通知功能。此时绑定引擎用TypeDescriptor来反射源对象。效率最低。

    B、数据源是一个CLR对象,属性也是一个CLR属性。对象通过INotifyPropertyChanged实现通知功能。此时绑定引擎直接反射源对象。效率稍微提高。

    C、数据源是一个DependencyObject,而且属性是一个DependencyProperty。此时不需要反射,直接绑定。效率最高。

    2.当一个CLR对象很大时,比如有1000个属性时,尽量把这个对象分解成很多很小的CLR对象。比如分成1000个只有一个属性的CLR对象。

    3. 当我们在列表(比如ListBox)显示了一个CLR对象列表(比如List)时,如果想在修改List对象后,ListBox也动态的反映这种变化。此时,我们应该使用动态的ObservableCollection对象绑定。而不是直接的更新ItemSource。两者的区别在于直接更新ItemSource会使WPF抛弃ListBox已有的所有数据,然后全部重新从List加载。而使用ObservableCollection可以避免这种先全部删除再重载的过程,效率更高。

    4. 尽量绑定IList而不是IEnumerable到ItemsControl。

    WPF性能优化八、其它性能建议

    1. 如果需要修改元素的Opacity属性,最后修改一个Brush的属性,然后用这个Brush来填充元素。因为直接修改元素的Opacity会迫使系统创建一个临时的Surface

    2. 用NavigationWindow的时候,尽量Update the client area by object,而不是URI

    3. 尽量不要使用ScrollBarVisibility=Auto

    第二部分

    由于项目的需要,我们的WPF程序需要运行在终端机上,

    运行平台:Windows XP Embedded

    硬件:Atom, 2GB Memory, GMA950,

    在测试的时候,我们发现整个程序的运行非常的慢,因为我们用到了多个线程,所以一开始怀疑是线程切换导致的。使用ProcessExplorer查看进程,意外的是,我们发现CPU主要都耗在了Rendering上。而且,需要特别注意的是,占用CPU的是内核态的代码。

    百思不得其解,上网搜索若干优化WPF性能的文章,并且打了若干补丁,将系统也升级到了SP3,结果依然。

    万般无奈之下,想到我们的程序背景使用的是一张1024x768大小的PNG图片,而Silverlight不支持PNG。WPF支持,而SilverLight不支持,很诡异,莫非是这个PNG图片有什么特殊之处?而我们现在在XPE上使用PNG恰恰是踩到了一个“地雷”?

    好吧,死马当活马医。于是我们将背景图片换成JPG格式。性能马上就飙上去了,几乎没有内核态代码要做的事情。

    原因究竟是什么呢?PNG和JPG有啥不同的地方呢?

    与微软的工程师交流,据说是“there is no hardware accelerated implementation of PNG encoder as far as I know ”,“probably the decoder takes a abnormal code path to decode the stuff into the system memory”。

    园子里的兄弟有研究这个的吗?

    PS:

    除了在XPE系统上,某些配置的XP也会有相同的问题。Vista及Server2008无此问题。

  • 相关阅读:
    UML笔记补充——活动图的简单理解(看书过程中看到的经典实例,记录下来,以免忘了)
    对UML笔记中状态图的补充
    UML笔记(九)
    UML笔记(十一)
    UML笔记(七)
    新的开始——C#
    UML笔记(八)
    UML笔记(十)
    机房收费系统画图总结
    Servlet 学习笔记4:HTTP应答状态
  • 原文地址:https://www.cnblogs.com/slteam/p/2388335.html
Copyright © 2011-2022 走看看