Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sorting large tables




On Mar 14, 2008, at 05:34, Daniel Child wrote:

@interface GenericRecord : NSObject <NSCopying>
{
  NSMutableArray *record;
  ... plus a couple ivars not used for the sort
}

Field access is slower because you have to call two methods instead of one - one of the generic recorder, and then the array objectAtIndex method. Consider using instance variables.


Why use a mutable array? it takes more memory and slower then non mutable array. Are your fields mutable?

For example, even if you wan to edit the table, you can make a mutable copy of a record, edit it, and set the edited record back in the generic record.

@interface GenericTable : NSObject <NSCoding>
{
  NSMutableArray *records; // the records of data
  ... plus a couple ivars not used for the sort
}

// IN GenericTable implementation
- (void) sortRecordsByField: (int) fieldNum;
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // experimental! initially ran without it...
NSArray *sortedArray;
void *i;
i = (void *) &fieldNum;
sortedArray = [records sortedArrayUsingFunction: sortGenericRecord context: i]; // FROZE AFTER 20 MIN OF EXECUTION HERE

Here you just made a copy of the 100,000 records array, and you have 200,000 records...


// [self setRecords: [NSArray arrayWithArray: sortedArray]];
[self setRecords: [NSMutableArray arrayWithArray: sortedArray]]; // DID NOT GET THIS FAR....

And here you do another copy; 300,000 records!

If you implement you setRecords: with copy - preventing someone from modifying your table behind your back, you have now 400,000 records in memory.


Instead sort the table in-place:

	[records sortUsingFunction:sortGenericRecord context:i];

	[pool release];
}

// in GenericRecord implementation
int sortGenericRecord (GenericRecord *rec1, GenericRecord *rec2, void *fieldNum)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int *columnPtr = (int *) fieldNum;
int column = *columnPtr;
NSString *rec1Field = [rec1 fieldAtIndex: column]; // no new alloc, just ptr assignment
NSString *rec2Field = [rec2 fieldAtIndex: column]; // ibid => how can I make smaller footprint?
NSLog(@"REC 1: %@ REC 2: %@\n", rec1Field, rec2Field);
return [rec1Field compare: rec2Field];
[pool release]; // I'm not sure whether the pool helps since no convenience constructors, but tried anyway.

Should be (if the pool is needed:

	int result = [rec1Field compare:rec2Field];
	[pool release];
	return result;

}


Best Regards,

Nir Soffer

_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/email@hidden

This email sent to email@hidden
References: 
 >Re: sorting large tables (From: Daniel Child <email@hidden>)
 >Re: sorting large tables (From: Jens Alfke <email@hidden>)
 >Re: sorting large tables (From: Daniel Child <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.