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
This commit is contained in:
Jens Ayton 2008-05-03 13:35:10 +00:00
parent ac894b5309
commit b3bace6ba2
2 changed files with 97 additions and 1 deletions

View File

@ -125,6 +125,9 @@ static NSString * const kWeightsKey = @"weights";
NSMutableArray *_weights; NSMutableArray *_weights;
float _sumOfWeights; float _sumOfWeights;
} }
- (id) initPrivWithObjectArray:(NSMutableArray *)objects weightsArray:(NSMutableArray *)weights sum:(float)sumOfWeights;
@end @end
@ -384,6 +387,13 @@ static OOEmptyProbabilitySet *sOOEmptyProbabilitySetSingleton = nil;
return [NSArray array]; 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 @end
@ -504,6 +514,12 @@ static OOEmptyProbabilitySet *sOOEmptyProbabilitySetSingleton = nil;
return [NSArray arrayWithObject:_object]; return [NSArray arrayWithObject:_object];
} }
- (id) mutableCopyWithZone:(NSZone *)zone
{
return [[OOConcreteMutableProbabilitySet allocWithZone:zone] initWithObjects:&_object weights:&_weight count:1];
}
@end @end
@ -685,6 +701,31 @@ static OOEmptyProbabilitySet *sOOEmptyProbabilitySetSingleton = nil;
return (index < _count) ? _objects[index] : 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 @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 - (id) initWithObjects:(id *)objects weights:(float *)weights count:(unsigned)count
{ {
unsigned long i = 0; 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 @end

View File

@ -2972,7 +2972,7 @@ static BOOL IsCandidateMainStationPredicate(Entity *entity, void *parameter)
#if PROFILE_SHIP_SELECTION #if PROFILE_SHIP_SELECTION
++profSlowPath; ++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 #endif
pset = [[[registry probabilitySetForRole:role] mutableCopy] autorelease]; pset = [[[registry probabilitySetForRole:role] mutableCopy] autorelease];