What we did to work around this was implement IBindingList on our own
using a hashlist .. you could also fairly easily override the behavior
to index your list in a derived class by overriding add/remove/etc
(note that if you go this route you will need to get out reflector to
make sure you raise the proper events etc and its a bad overall
design).

Cheers,

Greg

On 10/31/06, Krebs Kristofer <[EMAIL PROTECTED]> wrote:
Hi!

I found a weird thing while I was investigating a performance issue. We
use BindningList<T> as base class for our business object collections.
It seems that BindingList<T>.AddNew calls IndexOf(T item) (which has to
iterate and do Equals for all items in the collection to find it... it's
probably last) after the call to AddNewCore IF the item (of T) overrides
Equals or implements IEquatable<T>. This makes adding new items this way
go slower and slower. Adding object via the usual Add does not cause
this problem.

So, my question is why, and how can I avoid this behaviour? I any case;
beware of this...

Test code ("dry coded"):

TestEntityCollection coll = new TestEntityCollection();

// Takes forever on my machine i.e. at least 25 seconds....
for (int i = 0; i < 10000; i++) {
   TestEntity obj = coll.AddNew();
   obj.Name = "Name" + i;
}

// This is much faster, < 0.5 seconds
for (int i = 0; i < 10000; i++) {
   TestEntity obj = new TestEntity();
   obj.ID = Guid.NewGuid();
   obj.Name = "Name" + i;
   coll.Add(obj);
}
....

public class TestEntity : IEquatable<TestEntity>
{
    private Guid _id;
    private string _name;


    public Guid ID { get { return _id; } set { _id = value; } }
    public string Name { get { return _name; } set { _name = value; }


    // This causes bad performance on AddNew it seems, remove
IEquatable
    // implementation to see the difference. Overriding Equals(object)
    // causes the same thing
    public bool Equals(TestEntity other) {
        return ((object)other != null && this.ID.Equals(other.ID);
    }
}

public class TestEntityCollection : BindingList<TestEntity>
{
  public override object AddNewCore() {
     TestEntity item = new TestEntity();
     item.ID = Guid.NewGuid();  // Just an example of id initialization
     Add(item);
     return item;
  }
}

===================================
This list is hosted by DevelopMentor(r)  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com



--
If knowledge can create problems, it is not through ignorance that we
can solve them.

Isaac Asimov

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to