IMHO I think the example Draw a smooth 3D surface with WPF, XAML, and C# is pretty cool. Unfortunately it’s also a bit slow. It takes around 16 seconds to generate the three-dimensional scene. The program is generating 10,000 points and more than 19,000 triangles, so it’s doing a lot of work, but the earlier non-smooth example is lightning fast. So the question is, why is the smooth version so much slower? Is it something about the rendering engine (over which we have no control) or is it something about the way we’re building the smooth triangles (which we might be able to fix)?

The answer lies in the way the program creates and uses its points. The smooth version reuses points if possible. That means to add a new point, it first looks through all of the old ones to see if it is already present. It takes a lot of time to look through such a large array of points.

This example uses the following version of the `AddPoint` method.

// If the point already exists, return its index. // Otherwise create the point and return its new index. private int AddPoint(Point3DCollection points, Point3D point) { // See if the point exists. for (int i = points.Count - 1; i >= 0; i--) // for (int i = 0; i < points.Count; i++) { if ((point.X == points[i].X) && (point.Y == points[i].Y) && (point.Z == points[i].Z)) return i; } // We didn't find the point. Create it. points.Add(point); return points.Count - 1; }

This code is very similar to the previous (slow) version except it searches the array of points from back-to-front instead of front-to-back. Most of the time, the triangles share points with other triangles that were added relatively recently. In fact, most of the triangles share two points with the triangle that was added immediately before. One of those points was added in a previous row of triangles, so it’s back a ways in the array, but the other point was just added so it should be very near the array’s end.

By searching the array backwards, this version of the `AddPoint` method reduces the program’s startup time from 16 seconds to about 2 seconds. A pretty nice speed up with very little work!