Re: NSSet Inefficiency
Re: NSSet Inefficiency
- Subject: Re: NSSet Inefficiency
- From: Nat! <email@hidden>
- Date: Sun, 24 Mar 2002 20:11:07 +0100
Am Samstag den, 23. Mdrz 2002, um 15:11, schrieb Gerriet M.
Denkmann:
I have an app which creates about 2 million objects, halve of
these are different. And I want to keep only these different
objects.
1. strategy: NSMutableSet
set = [ NSMutableSet initWithCapacity: 0]
for( ii = 1 to 2000000)
create newThing[ii]
oldThing = [ set member: newThing ]
if ( oldThing == nil )
[ set addObject: newThing ]
else
[ newThing release ]
use oldThing
You write some strange Basic/Obj-C mixture :)
If you use a set you don't need to check for membership, that's why
you use a set in the first place, so this
set = [NSMutableSet set];
for( i = 0; i < 20000000; i++)
{
object = my_subroutine_returning_non_autoreleased_object( i);
[set addObject:object];
[object release];
}
is sufficient. A question of course is "how efficient does it need
to be ?". You can look at some of my articles with
http://www.mulle-kybernetik.com/artikel/Optimization/opti.html (Ch.
3 and onwards) for some ideas how to make above loop faster in
Objective-C.
If you want to handle 2 mio "Things" (-> game) as fast as possible
use C .
Interestingly in the following (random) test case NSMutableSet is
much faster (7.7 s) than NSMutableArray (12.8 s) just for adding
objects (NSMutableArray doesn't even test for duplicates). The cost
of creating and releasing objects alone was (5.1 s - somewhat too
much in comparison, since the objects are _really_ freed).
> Running 'setarray'...
2002-03-24 19:58:34.873 setarray[643] Start Array
2002-03-24 19:58:47.671 setarray[643] End array 2000000
2002-03-24 19:58:50.982 setarray[643] Start SET
2002-03-24 19:58:58.625 setarray[643] End SET 2000000
2002-03-24 19:59:01.884 setarray[643] Start alloc only
2002-03-24 19:59:06.975 setarray[643] End alloc only
> Finished running 'setarray'.
#import <Foundation/Foundation.h>
#define LOOPS 2000000
static NSNumber *my_subroutine_returning_non_autoreleased_object
( unsigned long i)
{
return( [[NSNumber alloc] initWithUnsignedLong:i]);
}
int main (int argc, const char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableSet *set;
NSMutableArray *array;
unsigned long i;
NSObject *object;
array = [[NSMutableArray alloc] initWithCapacity:LOOPS];
NSLog( @"Start Array");
for( i = 0; i < LOOPS; i++)
{
object = my_subroutine_returning_non_autoreleased_object( i);
[array addObject:object];
[object release];
}
NSLog( @"End array %d", [array count]);
[array release];
set = [[NSMutableSet alloc] initWithCapacity:LOOPS];
NSLog( @"Start SET");
for( i = 0; i < LOOPS; i++)
{
object = my_subroutine_returning_non_autoreleased_object( i);
[set addObject:object];
[object release];
}
NSLog( @"End SET %d", [set count]);
[set release];
NSLog( @"Start alloc only");
for( i = 0; i < LOOPS; i++)
{
object = my_subroutine_returning_non_autoreleased_object( i);
[object release];
}
NSLog( @"End alloc only");
[pool release];
return 0; // ...and make main fit the ANSI spec.
}
So NSMutableSet could be your friend. As Ondra suggested check your
hash method...
Nat!
------------------------------------------------------
Some people drink deep from the fountains of life, and
some just gargle. -- DLR
_______________________________________________
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.