Re: Slower with Cocoa subclass
Re: Slower with Cocoa subclass
- Subject: Re: Slower with Cocoa subclass
- From: "Alastair J.Houghton" <email@hidden>
- Date: Fri, 31 Oct 2003 14:38:12 +0000
On Friday, October 31, 2003, at 01:37 pm, Lorenzo wrote:
Hi,
when I run using the local functions "placeObject" and call
------------------------------------
- (void)drawRect:(NSRect)rect
{
int i;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
for(i = 0; i < totObjects; i++){
[self placeObject:i];
}
[[self openGLContext] flushBuffer];
}
[snip]
when I call
------------------------------------
- (void)drawRect:(NSRect)rect
{
int i;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
for(i = 0; i < [objectsToDraw count]; i++){
objectToDraw = [objectsToDraw objectAtIndex:i];
[objectToDraw placeObject];
}
[[self openGLContext] flushBuffer];
}
------------------------------------
everything runs slower.
I simply moved the previous routine "placeObject" from the "self" class
to the "SBCube" class. So, why now does my application run slower?
Look at your code :-)
In the first case, you are sending a single message per loop iteration.
In the second case, you are sending *three*. The first thing to do
would be to remember the result of [objectsToDraw count] (i.e. store it
in a local variable) rather than asking for it on each loop iteration.
If you really must have the absolute maximum performance for this
section of your code, then you could try something like this:
NSEnumerator *thingEnum = [objectsToDraw objectEnumerator];
IMP *placeObject = [myCube
instanceMethodForSelector:@selector(placeObject)];
IMP *nextObject = [thingEnum methodForSelector:@selector(nextObject)];
myCube *cube;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
while ((cube = nextObject (thingEnum, @selector(nextObject))))
placeObject (cube, @selector(placeObject));
[[self openGLContext] flushBuffer];
One thing I do wonder is whether it's faster to use an NSEnumerator, or
to index the array with -objectAtIndex:... you might like to try
typedef id (*obj_at_index_t)(id, SEL, unsigned);
obj_at_index_t objAtIndex = (obj_at_index_t) [objectsToDraw
methodForSelector:@selector(objectAtIndex:)];
IMP *placeObject = [myCube
instanceMethodForSelector:@selector(placeObject)];
unsigned index = 0;
unsigned max = [objectsToDraw count];
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
while (index < max) {
myCube *cube = objAtIndex (objectsToDraw, @selector(objectAtIndex:),
index++);
placeObject (cube, @selector(placeObject));
}
[[self openGLContext] flushBuffer];
and report which is faster.
(CAVEAT: Before doing any optimisations like this, you should profile
your code to find-out where the bottleneck is... if there is a
bottleneck somewhere else, then there's no point in making your code
more complicated like this. You should also profile *after*
optimisation, to make sure that what you have done really is an
optimisation [to give a specific example, some Windows code I've seen
made unnecessary use of assembly language because someone thought it'd
be faster, but because the compiler they were using disables
optimisation in functions that contain inline assembler, their entire
program ran significantly slower than it did when I replaced the
assembler with some C].)
Kind regards,
Alastair.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.