ElementName与RelativeResource?

Shi*_*mmy 16 wpf performance binding relativesource elementname

以下哪些TextBlocks的绑定会降低性能:

<Window  
  x:Name="Me"
  x:Class="MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  xmlns:src="clr-namespace:WpfApplication1" 
  Title="MainWindow">
  <StackPanel>
    <TextBlock Text="{Binding Title, ElementName=Me}"/>
    <TextBlock Text="{Binding Title, RelativeSource={RelativeSource AncestorType={x:Type src:MainWindow}}}"/>
  </StackPanel>    
</Window>
Run Code Online (Sandbox Code Playgroud)

我确信当TextBlocks处于具有许多兄弟和祖先的高嵌套级别时,我的问题可能会有所不同.

注意事项

(仅基于个人想法,我可能在每个特定的人中都错了!):

  • ElementName:

    • 可能会搜索并比较当前元素与更多控制,通过它的所有孩子,兄弟姐妹,叔叔和包括祖先在内的大叔(可能有所有注册名称的HashTable?)
    • 获取Name控件的属性应该比调用成本低GetType.
    • 比较字符串比比较类型便宜,特别是当您知道大多数控件甚至没有它们的Name设置时.
  • FindAncestor:

    • 只会通过祖先,而不是兄弟姐妹的"叔叔","表兄弟"等进行迭代.
    • 最有可能用于GetType确定祖先类型; GetType比简单的Name属性获取器(可能DP不同?)的性能更高

Ian*_*ths 27

通过争论你认为哪个更快,试图回答这类事情通常是一个可怕的想法.建立一个测量它的实验要好得多.

我稍微修改了你的设置 - 我将相关的Xaml放入UserControl,并绑定到Name属性,因为UserControl没有Title属性.然后我编写了一些代码来创建控件的新实例并将其添加到UI中,并使用它Stopwatch来测量构造和加载它所花费的时间.(我在构建用户控件之前开始计时,并在用户控件引发其Loaded事件后停止.)

DispatcherTimer每秒运行20次这样的代码,所以我可以进行大量的测量,以期减少实验误差.为了最大限度地减少由于调试和诊断代码引起的失真,我在Release版本中运行,我只计算并打印2000次迭代完成后的平均值.

在2000次迭代之后,该ElementName方法平均为887us.

在2000次迭代之后,该RelativeSource方法平均为959us.

因此ElementName,在这个特定的实验中,比...更快RelativeSource.加载一个简单UserControl的只有一个Grid和一个TextBlock只有一个命名元素的ElementName方法,该方法看起来需要92%的时间来加载该RelativeSource方法.

当然,我在这里测量一个小的,人为的例子.ElementName方法的性能可能会根据范围内有多少命名元素而有所不同.并且可能存在其他可能在实际情况中产生完全不同结果的意外因素.因此,如果您想获得更好的图片,我建议您在真实应用程序的上下文中执行类似的测量.

我用10个TextBlocks而不是1重复实验.ElementName然后平均2020us,而RelativeSource方法平均为2073us,两次测试再次超过2000次迭代.奇怪的是,这里有一个较小的差异,不仅仅是相对而言,而是绝对意义上 - 单元素的例子显示出72us的差异,其中十元素的例子显示出53us的差异.

我开始怀疑通过在我的主机上运行我的测试而导致更多的变化,而不是使用尽可能少的东西仔细配置以最小化噪音.

还有一个变体:仍然有10个绑定文本块,我向用户控件添加了10个空的,未绑定的命名文本块.这里的想法是引入更多命名的东西 - ElementName现在必须在11个命名的东西中找到一个命名的项目.现在的平均值为ElementName2775us.将RelativeSource这些额外的10种命名元素的方法在3041us出来.

同样,我怀疑我的台式机在这里变化 - 看起来很奇怪,RelativeSource这里的表现要比本来应该更ElementName有利的场景更糟糕.

不管怎么说,确实看起来相当清楚的是,这里装载的成本更为敏感元件的数量比是结合你使用哪一种风格.显然有一个小优势,ElementName但足够小(并且有足够奇怪的结果)会对有效性产生怀疑,认为它必然更快.

因此,我们可以构建更仔细的实验​​,以获得更好的画面.但在我看来,如果在普通计算机上运行时无法确定地表现出性能上的显着差异,那么基本上浪费时间来争论哪个更快.

总而言之:在这里关注表现是错误的.选择能够获得更具可读性的代码.