Question

Better solution for adding to a BindableCollection, seems really slow with more than 1000 objects being added. Unless I am missing something.

Was it helpful?

Solution

I think the reason why AddRange is slow is the fact that a lot of NotifyOnPropertyChanged events are fired. Caliburn itself does not raise events while adding a range, but BindableColletion calls its base ObservableCollection.InsertItem which in turn fires OnPropertyChanged and OnCollectionChanged on each Item. Copying the BindableColletion to a temporary List<>, AddRange the Long list to it and creating a new BindableCollection(temporary) seems to be faster.

I wrote a short benchmark. Note the BindableCollection in this example actually is not bound to anything, so in a real world scenario the benefit should be even greater.

   private static void Main()
        {
            DateTime startTime;
            TimeSpan elapsedTime;
            var longList = new List<int>(Enumerable.Range(1, 10000000));
            var bindableInts = new BindableCollection<int>(Enumerable.Range(1, 100));

            startTime = DateTime.Now;
            bindableInts.AddRange(longList);
            elapsedTime = DateTime.Now - startTime;

            Console.WriteLine("Time using AddRange: " + elapsedTime);

            bindableInts = new BindableCollection<int>(Enumerable.Range(1, 100));

            startTime = DateTime.Now;
            var temp = new List<int>(bindableInts);
            temp.AddRange(longList);
            bindableInts = new BindableCollection<int>(temp);
            elapsedTime = DateTime.Now - startTime;

            Console.WriteLine("Time using `temp List<>`: " + elapsedTime);
            Console.ReadLine();
        }

Output:

Time using AddRange: 00:00:00.7310548

Time using temp List<>: 00:00:00.1750151

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top