通过 Objective C++ 强大功能提高 iPhone 程序的性能
2010-02-10 00:23:00 来源:WEB开发网我准备了一个XCode项目,它包括了这里讨论的所有代码。此示例项目并未包括了所有点的原始数据库。它仅包含了一些世界地图上的随机数据。虽然与真实情况有所区别,但它们的处理方法与我收集的原始数据的大同小异。
第一种方法: 普通Cocoa方法
第一种方法十分简单而且并没有采用十分高效的方法。使用Object C对象(@class Spot)来表示位置,它们以NSArrary的形式被保存在一个数据库对象中(@class SpotsDB1)。
@interface Spot : NSObject {
CGPoint _position;
}
@property (nonatomic) CGPoint position;
@end
@interface SpotsDB1 : NSObject {
NSArray* _spots;
}
- (NSUInteger)countSpotsInRect:(CGRect)rect;
@end
为进行一个指定CGRect内地位置计数,数据库对象简单地循环整个数组并检查各位置。
NSUInteger count = 0;
for (Spot* spot in _spots) {
if (CGRectContainsPoint(aRect, spot.position))
++count;
}
使用上述代码,在总数为230,000个点的区域上的任意一个{0.02, 0.02}矩形内进行计数大概需要250毫秒。太糟糕了,如果你的目标是刷新率60Hz,那么你只有16 ms绘制一帧。使得此方案过慢的原因不仅在于其缺乏聪明的算法,而且在循环中浪费了许多时间在调用了几个函数上。另一个对性能产生负面影响的因素是位置被保存在NSArray中的对象,这是由于对象占用了大量的内存以及数组指针的非直接性导致了处理器时间的增加。
第二种方法: 简单优化
为使同样的方案运行得更快,我们只需简单地将位置存储与一个更为紧凑的数据结构中:一个CGPoint结构的标准C数组。为使用方便,我们将C数组保存在一个NSMutableData 对象中。
_spotCount = [spots count];
_spotsData = [[NSMutableData alloc] init];
for (Spot* spot in spots) {
CGPoint p = spot.position;
[data appendBytes:&p length:sizeof(CGPoint)];
}
消除了循环内函数调用的负面影响,我们使得性能有四倍的提升:
CGFloat xMin = CGRectGetMinX(aRect);
CGFloat yMin = CGRectGetMinY(aRect);
更多精彩
赞助商链接