Debdeep
Debdeep

Reputation: 241

performance impact ->modifying an object in Observable Collection vs Removing and adding a new object?

I have an observable collection of a particular type T. Now I have a listener set to third party service and I am getting an object T which is actually a modification to an existing object in that observable collection.

What should I do?

1>Find the object that has been modified and then one by one change all the properties to the newly obtained value

OR

2>just delete the object from the list and add the obtained object

Note: I can find the object from the collection by LINQ query using an Id property of class T and it is unique for each object. The question is after I find the object will I remove it and add the new one which has the same ID, or do I modify the existing one?

Upvotes: 3

Views: 1322

Answers (3)

Debdeep
Debdeep

Reputation: 241

Latest Updates(Thanks to @Alberto and @BlackBear for giving me directions):

I tested with XamGrid and observable collection of class T which has 10 properties binding to grid. Each property raises a notification only if its value changes. Also used dictionary approach of @Alberto.

Deleting and Addding approach takes about 3x to 4x time where as Modification Approach takes x time. However this holds good when your actual object and modified object has only difference in 2 to 3 properties(that means not all properties of actual object are different from the properties of modified object, just 2 properties are different, so raising just two notifications for property change.)

If your modified object has about 5 or 6 properties raising the notification then the performance of modification becomes same as removing and adding a row.

So bottom line is more the difference between actual and modified object more the time taken to modify it, and at a point of time you may think of dropping the actual object and adding the modified object.

For me standard modified object has a difference of 2 to 3 properties from the actual object and performance will be better for Modification of existing object.

Upvotes: 0

Brian Rasmussen
Brian Rasmussen

Reputation: 116401

This answer is in request to comment by OP.

You could implement a class, that supports bulk updates. To do that you need to provide method(s) that set the necessary values by accessing the underlying fields directly instead of going through the properties. Once all the values are set, you trigger notification for the entire object. Here's a simple class to illustrate the idea:

class BindableTypeThatSupportsBulkUpdate : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _Text1;
    public string Text1
    {
        get { return _Text1; }
        set { _Text1 = value; NotifyPropertyChanged(); }
    }

    private string _Text2;
    public string Text2
    {
        get { return _Text2; }
        set { _Text2 = value; NotifyPropertyChanged(); }
    }

    private void NotifyPropertyChanged([CallerMemberName]string name = "")
    {
        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    public void BulkUpdate(string t1, string t2)
    {
        _Text1 = t1;
        _Text2 = t2;

        // Passing String.Empty as the name causes notification to fire for all the     properties
        NotifyPropertyChanged(String.Empty);
    }
}

This is simplified, but you probably get the idea anyway.

The BulkUpdate method sets two fields and then triggers notification on the entire object. I.e. you'll only get a single update even if you update multiple values.

Upvotes: 0

Alberto
Alberto

Reputation: 15941

The first solution will be the fastest.

Adding and removing an object from an ObservableCollection is pretty slow. The remove-and-add operation will raise 2 CollectionChanged events.

The problem with the first solution can be the searching. You can use a more sophisticated search algorithm or you can use a dictionary to keep your items indexed by id.

For example:

class ComplexObj //Maybe should implement INotifyPropertyChanged
{
    public int Id{get;set;}
    public string SomeProperty{get;set;}
}

Dictionary<int, ComplexObj> lookup = new Dictionary<int, ComplexObj>();
ObservableCollection<ComplexObj> myCollection = new ObservableCollection<ComplexObj>();

When you add an item to the collection make sure to add it in the dictionary too:

public void AddNewObj(ComplexObj obj)
{
    lookup.Add(obj.Id, obj);
    myCollection.Add(obj);
}

Then when you need to update a specific object:

public void Update(ComplexObj obj)
{
     lookup[obj.Id].SomeProperty = obj.SomeProperty;
}

Upvotes: 1

Related Questions