Obj-C optimization woes

I am working on a routine to calculate averaged normals. I am pretty much using a c++ tutorial as my guide and tossing it write into one of my obj-c objects, so I rewrote it in obj-c. I thought this would be trivial but when the original is run it takes < 1 second to run thru the routine and calc all the normals, but my obj-c version takes over 30 seconds to run. Rather unacceptable if you ask me.

Most definelty a NSArray will be slower. I would be very suprised if it was this much slower though. These arrays contain Vectors which are objects as well, so I thought using all NSArrays would make it much easier. I will have to rework a huge portion of my code if the NSArrays are truly the problem. I highly doubt / hope it is not the problem.

I would not recommend using Obj-C classes for "tiny" classes like vectors, as there is some overhead when sending messages to Obj-C objects. I recommend either Obj-C++ so you can use C++ objects for "tiny" classes (ugly and painfully long compile times) or using some basic C structs for your vectors, etc. and manipulating them with C functions instead of Obj-C messages.

Without at least a little bit of timing of what inside the loop is taking the longest we'll never be able to help you (or for you to help yourself). Any of the method calls made inside your loop could be slowing it down. Finding out which of them is taking a lot of time is the secret to tuning your performance. See if you can use Shark to pinpoint which part of the loop is the slowest then concentrate there.

I did a Time Profile with shark and sampled from when this is running, and the biggest culprit is objc_msgSend at 23.3% of the load. Just as you all have suspected. I had no idea that objc method calls could be that expensive. Granted those loops are run depending on the mesh anywhere from 4 to 4000 times.

I guess the only place I can go is to alter my vector object. I would like to keep it as easy to use as possible, would going the ObjC++ route or the c structs route be best? Ease of use is what I am going for.

I have just learned ObjC a few months ago and when I started on this project I got a little over zealous with the ObjC object creation . I learned my lesson.

One thing you can do to speed up Objective-C messages is to get an IMP for the method you want to use. See NSObject's -instanceMethodForSelector:. This allows you to call the method by using a function pointer rather than objc_msgSend, and should give you a nice speed boost in tight loops like this.

That's a little better. But, frankly, if I were you I'd either let my vertices be a struct, with C functions to implement normalization and other vector ops, or I'd go the c++ route and make a vector class with operator overloading ( this is what I do, but I recognize that many people don't like C++ ).

Anyway, you've *got* to not treat vertices as generic NSArrays. That's WAY too generic: go with a struct, or a float [4], or a union overlapping the two...

ThemsAllTook Wrote:One thing you can do to speed up Objective-C messages is to get an IMP for the method you want to use. See NSObject's -instanceMethodForSelector:. This allows you to call the method by using a function pointer rather than objc_msgSend, and should give you a nice speed boost in tight loops like this.

I will more then likely move over to simple c functions to do my bidding , but in the mean time I would like to trudge onward with my development, and your idea of using an IMP for method calls keeps me from having to rip out large portions of code.

How would I go about doing this with an IMP for each method call?
So far I have only been able to figure out the simple first -doSomething selector, and even then I am not sure it will by-pass the obj-c overhead. And even still I am not sure how to use it. Pointers to functions are scarey in my book.

The first two arguments to an IMP are the object itself, and the selector of the method you're calling. After that, zero or more arguments depending on how many parameters the method takes. Hope that helps.

Thank you so much for the responces everyone. I was able to get it to run at a MUCH faster time.

I am still learning how to properly understand and use Shark for optimization but I was able to see that it wasn't really the objc_msgSend calls that were the problem. It was the fact I put a bunch of NSNumbers into a NSMutableArray, because every face can have as many points as it wants. But for calculating the normals I do not need every point, just three, so I created an array of size numFaces * three, and filled it with the first three points of every face.

The time it took to run this method on a mesh with 3000 verts went from ~25-30 seconds to less then a second.

Here is the obligitory, what I was able to create with your help picture: