From b3bace6ba2f9258c3e047e7d6d1851f1f7504658 Mon Sep 17 00:00:00 2001 From: Jens Ayton Date: Sat, 3 May 2008 13:35:10 +0000 Subject: [PATCH] Improved -copy and -mutableCopy performance for OOProbabilitySet. I thought I had a clever idea for an O(log n) mutable probability set last night, but can't remember it now. git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@1610 127b21dd-08f5-0310-b4b7-95ae10353056 --- src/Core/OOProbabilitySet.m | 96 +++++++++++++++++++++++++++++++++++++ src/Core/Universe.m | 2 +- 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/src/Core/OOProbabilitySet.m b/src/Core/OOProbabilitySet.m index f2083e8e..13865275 100644 --- a/src/Core/OOProbabilitySet.m +++ b/src/Core/OOProbabilitySet.m @@ -125,6 +125,9 @@ static NSString * const kWeightsKey = @"weights"; NSMutableArray *_weights; float _sumOfWeights; } + +- (id) initPrivWithObjectArray:(NSMutableArray *)objects weightsArray:(NSMutableArray *)weights sum:(float)sumOfWeights; + @end @@ -384,6 +387,13 @@ static OOEmptyProbabilitySet *sOOEmptyProbabilitySetSingleton = nil; return [NSArray array]; } + +- (id) mutableCopyWithZone:(NSZone *)zone +{ + // A mutable copy of an empty probability set is equivalent to a new empty mutable probability set. + return [[OOConcreteMutableProbabilitySet allocWithZone:zone] initPriv]; +} + @end @@ -504,6 +514,12 @@ static OOEmptyProbabilitySet *sOOEmptyProbabilitySetSingleton = nil; return [NSArray arrayWithObject:_object]; } + +- (id) mutableCopyWithZone:(NSZone *)zone +{ + return [[OOConcreteMutableProbabilitySet allocWithZone:zone] initWithObjects:&_object weights:&_weight count:1]; +} + @end @@ -685,6 +701,31 @@ static OOEmptyProbabilitySet *sOOEmptyProbabilitySetSingleton = nil; return (index < _count) ? _objects[index] : nil; } + +- (id) mutableCopyWithZone:(NSZone *)zone +{ + id result = nil; + float *weights = NULL; + unsigned long i = 0; + float weight = 0.0f, sum = 0.0f; + + // Convert cumulative weights to "plain" weights. + weights = malloc(sizeof *weights * _count); + if (weights == NULL) return nil; + + for (i = 0; i < _count; ++i) + { + weight = _cumulativeWeights[i]; + weights[i] = weight - sum; + sum += weight; + } + + result = [[OOConcreteMutableProbabilitySet allocWithZone:zone] initWithObjects:_objects weights:weights count:_count]; + free(weights); + + return result; +} + @end @@ -754,6 +795,22 @@ static OOEmptyProbabilitySet *sOOEmptyProbabilitySetSingleton = nil; } +// For internal use by mutableCopy +- (id) initPrivWithObjectArray:(NSMutableArray *)objects weightsArray:(NSMutableArray *)weights sum:(float)sumOfWeights +{ + assert(objects != nil && weights != nil && [objects count] == [weights count] && sumOfWeights >= 0.0f); + + if ((self = [super initPriv])) + { + _objects = objects; + _weights = weights; + _sumOfWeights = sumOfWeights; + } + + return self; +} + + - (id) initWithObjects:(id *)objects weights:(float *)weights count:(unsigned)count { unsigned long i = 0; @@ -929,6 +986,45 @@ static OOEmptyProbabilitySet *sOOEmptyProbabilitySetSingleton = nil; } } + +- (id) copyWithZone:(NSZone *)zone +{ + id result = nil; + id *objects = NULL; + float *weights = NULL; + unsigned long i = 0, count = 0; + + count = [_objects count]; + if (EXPECT_NOT(count == 0)) return [OOEmptyProbabilitySet singleton]; + + objects = malloc(sizeof *objects * count); + weights = malloc(sizeof *weights * count); + if (objects != NULL && weights != NULL) + { + [_objects getObjects:objects]; + + for (i = 0; i < count; ++i) + { + weights[i] = [_weights floatAtIndex:i]; + } + + result = [[OOProbabilitySet probabilitySetWithObjects:objects weights:weights count:count] retain]; + } + + if (objects != NULL) free(objects); + if (objects != NULL) free(weights); + + return result; +} + + +- (id) mutableCopyWithZone:(NSZone *)zone +{ + return [[OOConcreteMutableProbabilitySet alloc] initPrivWithObjectArray:[_objects mutableCopyWithZone:zone] + weightsArray:[_weights mutableCopyWithZone:zone] + sum:_sumOfWeights]; +} + @end diff --git a/src/Core/Universe.m b/src/Core/Universe.m index 52358a6b..d2f0edf0 100644 --- a/src/Core/Universe.m +++ b/src/Core/Universe.m @@ -2972,7 +2972,7 @@ static BOOL IsCandidateMainStationPredicate(Entity *entity, void *parameter) #if PROFILE_SHIP_SELECTION ++profSlowPath; - OOLog(@"shipRegistry.selection.profile", @"Hit slow path in ship selection for role \"%@\", having selected ship \"%@\". Now %lu of %lu on slow path (%f%%).", role, shipKey, profSlowPath, profTotal, ((double)profSlowPath)/((double)profTotal)); + OOLog(@"shipRegistry.selection.profile", @"Hit slow path in ship selection for role \"%@\", having selected ship \"%@\". Now %lu of %lu on slow path (%f%%).", role, shipKey, profSlowPath, profTotal, ((double)profSlowPath)/((double)profTotal) * 100.0f); #endif pset = [[[registry probabilitySetForRole:role] mutableCopy] autorelease];