パフォーマンスの最適化:データ バインディングOptimizing Performance: Data Binding

Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) データ バインディングは、データを表示したり操作するための単純で一貫した方法をアプリケーションに提供します。data binding provides a simple and consistent way for applications to present and interact with data. 要素は、CLRCLR オブジェクトおよび XMLXML の形式のさまざまなデータ ソースのデータにバインドできます。Elements can be bound to data from a variety of data sources in the form of CLRCLR objects and XMLXML.

このトピックでは、データ バインディングのパフォーマンスに関する推奨事項について説明します。This topic provides data binding performance recommendations.

データ バインディングの参照が解決されるしくみHow Data Binding References are Resolved

データ バインディングのパフォーマンスの問題に入る前に、Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) のデータ バインディング エンジンがバインディングのオブジェクト参照をどのように解決するのかを説明します。Before discussing data binding performance issues, it is worthwhile to explore how the Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) data binding engine resolves object references for binding.

Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) のデータ バインディングでは、任意の CLRCLR オブジェクトをソースとして使用して、The source of a Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) data binding can be any CLRCLR object. CLRCLR オブジェクトのプロパティ、サブプロパティ、インデクサーにバインドできます。You can bind to properties, sub-properties, or indexers of a CLRCLR object. いずれかの Microsoft .NET Framework のリフレクションを使用して、バインド参照が解決またはICustomTypeDescriptorします。The binding references are resolved by using either Microsoft .NET Framework reflection or an ICustomTypeDescriptor. 次に、バインディングのオブジェクト参照を解決するための 3 つの方法について説明します。Here are three methods for resolving object references for binding.

1 つ目は、リフレクションを使用する方法です。The first method involves using reflection. ここで、PropertyInfoオブジェクトがプロパティの属性を探索するために使用し、プロパティのメタデータへのアクセスを提供します。In this case, the PropertyInfo object is used to discover the attributes of the property and provides access to property metadata. 使用する場合、ICustomTypeDescriptorプロパティの値にアクセスするインターフェイス、データ バインディング エンジンはこのインターフェイス。When using the ICustomTypeDescriptor interface, the data binding engine uses this interface to access the property values. ICustomTypeDescriptorインターフェイスはオブジェクトが静的な一連のプロパティがない場合に特に便利です。The ICustomTypeDescriptor interface is especially useful in cases where the object does not have a static set of properties.

プロパティの変更通知を実装するか指定することができます、INotifyPropertyChangedインターフェイスかに関連付けられている変更通知を使用して、TypeDescriptorします。Property change notifications can be provided either by implementing the INotifyPropertyChanged interface or by using the change notifications associated with the TypeDescriptor. ただし、プロパティの変更通知を実装するための推奨される戦略は、使用するINotifyPropertyChangedします。However, the preferred strategy for implementing property change notifications is to use INotifyPropertyChanged.

ソース オブジェクトがある場合、CLRCLRオブジェクト ソースのプロパティが、CLRCLRプロパティ、Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF)ソース オブジェクトでリフレクションを使用して取得する最初のデータ バインディング エンジンが、 TypeDescriptor、クエリを実行し、 PropertyDescriptorIf the source object is a CLRCLR object and the source property is a CLRCLR property, the Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) data binding engine has to first use reflection on the source object to get the TypeDescriptor, and then query for a PropertyDescriptor. パフォーマンスの観点から見た場合、このリフレクション操作のシーケンスには非常に時間がかかる可能性があります。This sequence of reflection operations is potentially very time-consuming from a performance perspective.

オブジェクト参照を解決するための 2 つ目の方法では、CLRCLRを実装するソース オブジェクト、INotifyPropertyChangedインターフェイス、およびソースのプロパティが、CLRCLRプロパティ。The second method for resolving object references involves a CLRCLR source object that implements the INotifyPropertyChanged interface, and a source property that is a CLRCLR property. この場合、データ バインディング エンジンは、ソースの型に対してリフレクションを直接使用して必要なプロパティを取得します。In this case, the data binding engine uses reflection directly on the source type and gets the required property. この方法も最適な方法とは言えませんが、最初の方法よりは作業セットの要件の負荷が小さくなります。This is still not the optimal method, but it will cost less in working set requirements than the first method.

オブジェクト参照を解決するための 3 番目の方法では、ソース オブジェクトが、DependencyObjectとソースのプロパティが、DependencyPropertyします。The third method for resolving object references involves a source object that is a DependencyObject and a source property that is a DependencyProperty. この場合、データ バインディング エンジンはリフレクションを使用する必要はありません。In this case, the data binding engine does not need to use reflection. 代わりに、プロパティ エンジンとデータ バインディング エンジンが連携してプロパティ参照を個別に解決します。Instead, the property engine and the data binding engine together resolve the property reference independently. これが、データ バインディングに使用されているオブジェクト参照を解決するための最適な方法です。This is the optimal method for resolving object references used for data binding.

速度のデータ バインディングの比較を次の表に、 Text 1,000 プロパティTextBlockこれら 3 つのメソッドを使用して要素。The table below compares the speed of data binding the Text property of one thousand TextBlock elements using these three methods.

TextBlock の Text プロパティのバインド先Binding the Text property of a TextBlock バインディング時間 (ミリ秒)Binding time (ms) レンダリング時間 -- バインディングを含む (ミリ秒)Render time -- includes binding (ms)
CLRCLR オブジェクトのプロパティTo a property of a CLRCLR object 115115 314314
プロパティに、CLRCLRを実装するオブジェクト INotifyPropertyChangedTo a property of a CLRCLR object which implements INotifyPropertyChanged 115115 305305
DependencyPropertyDependencyObjectします。To a DependencyProperty of a DependencyObject. 9090 263263

大きな CLR オブジェクトへのバインディングBinding to Large CLR Objects

何千ものプロパティを持つ 1 つの CLRCLR オブジェクトへのデータ バインディングは、パフォーマンスに大きな影響を及ぼします。There is a significant performance impact when you data bind to a single CLRCLR object with thousands of properties. この影響を最小限に抑えるには、その 1 つのオブジェクトを複数の CLRCLR オブジェクトに分割して、個々のオブジェクトのプロパティの数を減らします。You can minimize this impact by dividing the single object into multiple CLRCLR objects with fewer properties. 次の表は、1 つの大きな CLRCLR オブジェクトへのデータ バインディングと複数の小さなオブジェクトへのデータ バインディングのバインディング時間とレンダリング時間を示しています。The table shows the binding and rendering times for data binding to a single large CLRCLR object versus multiple smaller objects.

1000 個の TextBlock オブジェクトのデータ バインディングのバインド先Data binding 1000 TextBlock objects バインディング時間 (ミリ秒)Binding time (ms) レンダリング時間 -- バインディングを含む (ミリ秒)Render time -- includes binding (ms)
1000 個のプロパティを持つ 1 つの CLRCLR オブジェクトTo a CLRCLR object with 1000 properties 950950 12001200
1 つのプロパティを持つ 1000 個の CLRCLR オブジェクトTo 1000 CLRCLR objects with one property 115115 314314

ItemsSource へのバインディングBinding to an ItemsSource

必要があるシナリオを検討してください、 CLRCLR List<T>に表示する従業員の一覧を保持するオブジェクト、ListBoxします。Consider a scenario in which you have a CLRCLR List<T> object that holds a list of employees that you want to display in a ListBox. これら 2 つのオブジェクト間の通信を作成するには、従業員リストをバインドする、ItemsSourceのプロパティ、ListBoxします。To create a correspondence between these two objects, you would bind your employee list to the ItemsSource property of the ListBox. ここで、グループに新しい従業員が加わったとします。However, suppose you have a new employee joining your group. この新しいユーザーをバインドに挿入するためにできるように思うかもしれませんListBox値、単に従業員一覧にこのユーザーを追加し、その変更が自動的にデータ バインディング エンジンによって認識されるには。You might think that in order to insert this new person into your bound ListBox values, you would simply add this person to your employee list and expect this change to be recognized by the data binding engine automatically. その想定が false; を証明します。実際には、変更は反映されませんで、ListBox自動的にします。That assumption would prove false; in actuality, the change will not be reflected in the ListBox automatically. これは、ため、 CLRCLR List<T>オブジェクトがコレクション変更イベントを自動的に発生しません。This is because the CLRCLR List<T> object does not automatically raise a collection changed event. 取得するために、ListBox変更内容を選択するには、従業員の一覧を再作成し、再アタッチする必要が、ItemsSourceのプロパティ、ListBoxします。In order to get the ListBox to pick up the changes, you would have to recreate your list of employees and re-attach it to the ItemsSource property of the ListBox. この解決方法で問題は解決されますが、パフォーマンスへの影響はきわめて大きくなります。While this solution works, it introduces a huge performance impact. 再割り当てするたびに、ItemsSourceListBoxで新しいオブジェクトに、ListBoxまずすぐ前の項目をスローし、リスト全体を再生成します。Each time you reassign the ItemsSource of ListBox to a new object, the ListBox first throws away its previous items and regenerates its entire list. 場合、パフォーマンスに与える影響が拡大され、 ListBox 、複雑なマップDataTemplateします。The performance impact is magnified if your ListBox maps to a complex DataTemplate.

この問題を非常に効率的なソリューションは、従業員リストするためには、ObservableCollection<T>します。A very efficient solution to this problem is to make your employee list an ObservableCollection<T>. ObservableCollection<T>オブジェクト データ バインディング エンジンが受信できる変更通知を発生させます。An ObservableCollection<T> object raises a change notification which the data binding engine can receive. イベントを追加またはから項目を削除するItemsControlリスト全体を再生成する必要はありません。The event adds or removes an item from an ItemsControl without the need to regenerate the entire list.

更新にかかる時間以下の表、 ListBox (UI 仮想化はオフ) に 1 つの項目が追加されます。The table below shows the time it takes to update the ListBox (with UI virtualization turned off) when one item is added. 最初の行の数が経過時間を表すときに、 CLRCLR List<T>オブジェクトにバインドするListBox要素のItemsSourceします。The number in the first row represents the elapsed time when the CLRCLR List<T> object is bound to ListBox element's ItemsSource. 2 番目の行の数が経過時間を表すときに、ObservableCollection<T>にバインドされて、ListBox要素のItemsSourceします。The number in the second row represents the elapsed time when an ObservableCollection<T> is bound to the ListBox element's ItemsSource. 注: 使用する膨大な時間節約、ObservableCollection<T>データ バインディング方法。Note the significant time savings using the ObservableCollection<T> data binding strategy.

ItemsSource のデータ バインディングのバインド先Data binding the ItemsSource 1 項目の更新時間 (ミリ秒)Update time for 1 item (ms)
CLRCLR List<T>オブジェクトTo a CLRCLR List<T> object 16561656
に、 ObservableCollection<T>To an ObservableCollection<T> 2020

IEnumerable ではなく IList を ItemsControl にバインドするBind IList to ItemsControl not IEnumerable

バインドのどちらかがある場合、IList<T>またはIEnumerableItemsControlオブジェクトで、選択、IList<T>オブジェクト。If you have a choice between binding an IList<T> or an IEnumerable to an ItemsControl object, choose the IList<T> object. バインドIEnumerableItemsControl強制的WPFWPFラッパーを作成するIList<T>オブジェクトで、2 番目のオブジェクトの不要なオーバーヘッドによって、パフォーマンスが影響を受けることを意味します。Binding IEnumerable to an ItemsControl forces WPFWPF to create a wrapper IList<T> object, which means your performance is impacted by the unnecessary overhead of a second object.

データ バインディングのためだけに CLR オブジェクトを XML に変換しないDo not Convert CLR objects to XML Just for Data Binding.

WPFWPF では、XMLXML コンテンツへのデータ バインディングが可能です。ただし、XMLXML コンテンツへのデータ バインディングは、CLRCLR オブジェクトへのデータ バインディングに比べて低速です。allows you to data bind to XMLXML content; however, data binding to XMLXML content is slower than data binding to CLRCLR objects. CLRCLR オブジェクトのデータをデータ バインディングのためだけに XML に変換しないでください。Do not convert CLRCLR object data to XML if the only purpose is for data binding.

関連項目See also