我目前正在为地图视图中的兴趣点开发一个群集框架。 为了生成集群,我目前正在使用一种缓慢但非常精确的算法。
while(self.clusteringData.count>=2){
minDistance = DBL_MAX;
for (ClusterAnnotation *objectA in self.clusteringData) {
for (ClusterAnnotation *objectB in self.clusteringData) {
if (objectA != objectB) {
locationA.latitude = objectA.latitude;
locationA.longitude = objectA.longitude;
locationB.latitude = objectB.latitude;
locationB.longitude = objectB.longitude;
CLLocationDistance distance = [ClusterBuilder distanceBetweenLocation:locationA andLocation:locationB];
if(distance < minDistance){
minDistance = distance;
left = objectA;
right = objectB;
if(minDistance == 0.0){
break;
}
}
}
}
if(minDistance == 0.0){
break;
}
}
[self notifyDelegateClusteringProgress:((float)i/(float)j)];
ClusterTree* newRoot = [[ClusterTree alloc] initWithLeftClusterAnnotation:left rightClusterAnnotation:right];
[newRoot setDistance:minDistance];
[self.clusteringData addObject:newRoot];
[self.clusteringData removeObject:left];
[self.clusteringData removeObject:right];
left = nil;
right = nil;
root = newRoot;
}
第一次迭代非常快 - 即使它们应该是最慢的。然而,每次迭代时性能会变差,然后随着留给群集的项目减少而变得更好。
我知道在使用O(n ^ 3)算法时我不能期望良好的性能,但是第一次迭代需要大约0.009秒,并且该时间随着每次迭代而增加(即使它应该减少因为算法减少了数据每次迭代1项)。 我无法向自己解释为什么会这样。
我确定了while循环的每次迭代需要1000个项目的时间。 http://pastebin.com/8XsZuEks
群集线程在DISPATCH_QUEUE_PRIORITY_HIGH上运行,并在整个群集过程中使用99%的CPU。 在主提示上运行该进程并未修复性能下降。所以我猜它不是GCD /优先问题。
答案 0 :(得分:1)
你的迭代循环内置了一些中断,这意味着它并不总是每次都完成整个数组。性能变化是由于填充的数组和中断。
试想一下,如果你没有那些休息时间,每次迭代花费超过1.3秒(就像链接中最糟糕的情况一样)......
答案 1 :(得分:0)
尝试打印列表中的对象数以及迭代时间。也许奇怪的事情发生在对象的数量上?
除此之外,在进行任何优化工作之前,显然性能分析很重要。
只有1000个对象,这可能是浪费时间,但您可以考虑使用IMP函数指针调用替换内部循环体中的Objective-C消息调用。我认为常规C调用比消息传递快4-5倍。就时钟周期而言,没有太大差异,但如果您的数据有可能增长,那么它可能是值得的。