Re: Slower with Cocoa subclass
Re: Slower with Cocoa subclass
- Subject: Re: Slower with Cocoa subclass
- From: Lorenzo <email@hidden>
- Date: Sat, 01 Nov 2003 15:57:57 +0100
Hi,
thanks for your suggestions. They look like a totally new methods for me.
I am trying to implement them but I have some problem understanding.
May you please tell me the following?
Did you mean to do this way?
---------------
- (void)drawRect:(NSRect)rect
{
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];
}
---------------
I think that
NSEnumerator *thingEnum = [objectsToDraw objectEnumerator];
and the other 3 code lines could be done in a different method.
IMP *placeObject = [myCube
instanceMethodForSelector:@selector(placeObject)];
Does placeObject refer to myCube object only or to the myCube's class
generally?
I let you know that myCube is an object of the class SBCube, and placeObject
is a method of the SBCube class.
So in the current main class header I declared
SBCube *myCube;
And I don't understand the following statement:
myCube *cube;
---------------
So may you please make me understand this (new for me) technic?
As far as the second way you suggested, well, first please let me understand
the first one... :-)
Thank you.
Best Regards
--
Lorenzo
email: email@hidden
>
From: "Alastair J.Houghton" <email@hidden>
>
Date: Fri, 31 Oct 2003 14:38:12 +0000
>
To: Lorenzo <email@hidden>
>
Cc: email@hidden
>
Subject: Re: Slower with Cocoa subclass
>
>
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.