ChunkList<T> Class
A collection that improves performance in applications where you handle large and frequent data source updates.
Namespace: DevExpress.Xpf.ChunkList
Assembly: DevExpress.Xpf.Core.v24.1.dll
NuGet Package: DevExpress.Wpf.Core
Declaration
public class ChunkList<T> :
IList<T>,
ICollection<T>,
IEnumerable<T>,
IEnumerable,
IBindingList,
IList,
ICollection,
IListChanging
Type Parameters
Name | Description |
---|---|
T | The type of elements in the ChunkList collection. |
Remarks
Overview
The ChunkList is an optimized collection that stores data items in fixed-sized sublists called chunks. To access an item, use the following indexes:
- An index of a chuck that contains the item
- An index of the item within the chunk
In the ChunkList, the IndexOf, Insert, and Remove operations are limited only to a specific chunk and do not need to iterate through all items. As a result, these operations work much faster than in an ordinary list.
The table below illustrates the difference in performance between the BindingList and the ChunkList.
Scenario (1,000,000 items) | BindingList Standalone | ChunkList Standalone | BindingList Bound to GridControl | ChunkList Bound to GridControl |
---|---|---|---|---|
Creation time | 1016 | 1171 | 1422 | 2016 |
Insert 10000 items | 6422 | 250 | 7765 | 469 |
Remove 10000 items | 9700 | 219 | 8400 | 438 |
Update 10000 items | 58700 | 156 | 59328 | 250 |
Full iteration | 47 | 328 | ||
Memory used (MB) | 59 | 90 | ||
Sort string property | 7485 | 8187 | ||
Sort int property | 2465 | 3313 |
The ChunkList might work slower than ordinary collections if you apply multiple operations that iterate through all collection items (for example, data sort and filter, summary calculation).
Implement ChunkList
The ChunkList<T> constructor accepts an approximate size of the collection as the capacity parameter.
A chunk size is calculated as the square root of the capacity value. If you want to specify a custom chunk size, pass it as the chunkSize parameter of the ChunkList<T> constructor.
You can use one of the following techniques to store a chunk index for each data object:
Implement IChunkListObject
Implement the IChunkListObject interface in your data object class. This interface includes the ChunkObject property, which stores a chunk index in a field at the object level.
Advantage: A data source is generated faster and consumes less memory.
Disadvantage: This method requires data object modification.
public class DataObject : IChunkListObject {
public int NumericField { get; set; }
public string StringField { get; set; }
public object ChunkObject { get; set; }
}
public class DataSource {
public ChunkList<DataObject> Data { get; set; }
public DataSource() {
Data = new ChunkList<DataObject>(capacity: 1000000);
for (int i = 0; i < 1000000; i++) {
Data.Add(new DataObject());
}
}
}
Use Chunks Cache
Set the useChunksCache parameter of the ChunkList<T> constructor to true to create a hash table that stores chunk indexes for collection items.
Advantage: This method does not require data object modification.
Disadvantage: The hash table requires additional memory.
public class DataObject {
public int NumericField { get; set; }
public string StringField { get; set; }
}
public class DataSource {
public ChunkList<DataObject> Data { get; set; }
public DataSource() {
Data = new ChunkList<DataObject>(capacity: 1000000, useChunksCache: true);
for (int i = 0; i < 1000000; i++) {
Data.Add(new DataObject());
}
}
}
Set the supportPropertyChanged parameter to true to enable each chunk to listen to PropertyChanged events separately. As a result, you do not need to determine the chunk index for an item to find its position in the list. Note that this technique does not optimize the IndexOf operation.
public class DataObject : INotifyPropertyChanged {
private int numericField;
private string stringField;
public int NumericField {
get { return numericField; }
set {
numericField = value;
OnPropertyChanged("NumericField");
}
}
public string StringField {
get { return stringField; }
set {
stringField = value;
OnPropertyChanged("StringField");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) {
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public class DataSource {
public ChunkList<DataObject> Data { get; set; }
public DataSource() {
Data = new ChunkList<DataObject>(chunkSize: 1000, supportPropertyChanged: true);
for (int i = 0; i < 1000000; i++) {
Data.Add(new DataObject());
}
}
}