So I have been doing some 3D work that meshes whose Position and Normal collections are rapidly changing. I have been finding that I can either allocate new Position and Normal collections each frame, thus incurring a huge memory allocation overhead, or I can try to re-use the collections, which incurs a huge overhead firing off Changed events for every new item I change.
Having looked in vain for a BeginUpdate/EndUpdate type of pattern that applies to these classes, I stumbled upon a technique that seems to create something like it.
Consider the following code:
mesh.Positions.Clear();
for (int i = 0; i < 1000; i++) mesh.Positions.Add(new Point3D(i, i, i));
Now consider this code, which runs about 5 times faster.
Point3DCollection points = mesh.Positions;
mesh.Positions = null;
points.Clear();
for (int i = 0; i < 1000; i++) points.Add(new Point3D(i, i, i));
mesh.Positions = points;
The reason why it runs faster is that the overhead of firing the Changed event on the Point3DCollection has gone away while it has no 'parent'.
If Point3DCollection (and its ilk) implemented an
AddRange(IEnumerable<T> items) that looked to see if 'items'
implemented ICollection.CopyTo (probably leveraging Array.Copy under
the hood), it could be 3 times faster again.
I havent as yet experiemented with more complex collection classes, such as Model3DCollection, but I would guess that this "remove from parent, make modifications, re-insert" strategy might have other applications. A warning: Im pretty sure that when adding a model into the scene graph, the bounding box needs to be computed by transforming and traversing the entire subtree's meshes, in software, so this strategy may well not pay off in those cases. Anyone from MSFT care to comment

A performance hint for working with XXXCollection classes
PaulMCiti
The stated technique of removing a collection from the active tree and then reintroducing it seems to acheive the required purpose with very clean intent. Having a Begin/End type API on top of that seems both redundant and error prone. With the provided method failing to put the collection back will have more obvious results than failing to end the update mode. Modes are in general a bad idea in my experience, they greatly complicate testing and also make the API harder to use.
What may be well worth doing is support for the bulk copy option, and documenting this as a pattern to be used in many situations.
Chris Greenwood
I think the original poster suggests a great solution using an existing and well known pattern of BeginUpdate/EndUpdate. People are familiar with this pattern already and it seems a lot more friendly than having to allocate your own collection outside of the "real" collection to do temporary work in.
Any chance we could see this pattern introduced
Cheers,
Drew
RohitAggarwal
In WPF, I would say that the key to success is knowing the cost of various operations. Unfortunately, in WPF, the things we instinctively believe to be simple and fast operations, and Im thinking of index and property accessors here, are much more involved and can result in chains of causality way beyond the current focus.
Its probably a bit unrealistic, but if every method and every acessor had its performance characteristics documented in broad terms, including but not limited to big-O notation, well then, that would be a wonderful thing.
ambujkn
Yes, things tend to be much faster if you make bulk changes outside the tree. For example, the rule is to build big structures from the bottom: if you have a complex tree of Elements, hook up the lower levels, then add them to the higher levels and finally add the root into your scene graph when everything is set up. WPF defers what it can, but even that has overhead.
I'll leave it somebody else to comment specifically on 3D.