2011-04-26 81 views
3

我有下面的代码,将JSON字符串解码为一个对象数组,然后可以在UITableView中使用。优化慢代码 - 枚举字典

起初我以为JSON解码是慢的部分,但它似乎并不像“字典完成”几乎立即出现。

有关如何让代码更快一点的任何想法?

-(void)parseJSON:(NSString *)jsonData{ 

    NSLog(@"Start parsing"); 
    NSDictionary *deserializedData = [jsonData objectFromJSONString]; 
    NSLog(@"Dictionary Done"); 

    NSArray *flights = [deserializedData valueForKeyPath:@"flights.flight"]; 
    NSMutableArray *localArray = [[NSMutableArray alloc] init ]; 
    NSString *lastFlightno [email protected]""; 

    for (NSDictionary *flight in flights){ 

     ArchiveFlight *aFlight = [[ArchiveFlight alloc] initWithFlightno:[flight objectForKey:@"flightno"] route:[flight objectForKey:@"route"]]; 
     aFlight.flightID = [flight objectForKey:@"primary_key"]; 
     aFlight.timeStamp = [aFlight niceDate:[flight objectForKey:@"timestamp"]]; 

     if (![lastFlightno isEqualToString:aFlight.flightno]) { 
      [localArray addObject:aFlight]; 
     } 

     lastFlightno =aFlight.flightno; 
     [aFlight release]; 
    } 
    NSLog(@"End Parsing"); 
    [self loadupTable:localArray]; 
    self.flightArray = localArray; 
    [localArray release]; 

} 

编辑:添加时间戳

时间戳如下NSLogs的...

2011-04-26 13:22:36.104 App[1778:707] Finished request 
2011-04-26 13:22:36.109 App[1778:707] Start parsing 
2011-04-26 13:22:36.128 App[1778:707] Dictionary Done 
2011-04-26 13:22:37.713 App[1778:707] End Parsing 

样品的JSON的...

{"flights":[{"flight":{"flightno":"RYR54WP","timestamp":"2011-04-26 12:13:04","route":"EGNX-LEAL","primary_key":"836453"}},{"flight":{"flightno":"RYR24LU","timestamp":"2011-04-26 09:14:03","route":"EVRA-EGNX","primary_key":"831318"}},{"flight":{"flightno":"RYR39WH","timestamp":"2011-04-26 05:33:03","route":"EGNX-EVRA","primary_key":"825492"}},{"flight":{"flightno":"RYR7PX","timestamp":"2011-04-25 20:07:03","route":"LELC-EGNX","primary_key":"816703"}},{"flight":{"flightno":"RYR2VB","timestamp":"2011-04-25 16:57:06","route":"EGNX-LELC","primary_key":"810900"}},{"flight":{"flightno":"RYR3JN","timestamp":"2011-04-25 12:36:04","route":"GCTS-EGNX","primary_key":"802631"}},{"flight":{"flightno":"RYR8GV","timestamp":"2011-04-25 06:07:03","route":"EGNX-GCTS","primary_key":"792945"}},{"flight":{"flightno":"RYR82QR","timestamp":"2011-04-24 19:42:04","route":"EPKK-EGNX","primary_key":"783306"}},{"flight":{"flightno":"RYR51PV","timestamp":"2011-04-24 16:31:05","route":"EGNX-EPKK","primary_key":"777835"}},{"flight":{"flightno":"RYR53AQ","timestamp":"2011-04-24 14:09:05","route":"LIME-EGNX","primary_key":"773572"}},{"flight":{"flightno":"RYR1CX","timestamp":"2011-04-24 11:02:05","route":"EGNX-LIME","primary_key":"768285"}},{"flight":{"flightno":"RYR9ZW","timestamp":"2011-04-24 08:21:04","route":"LEGE-EGNX","primary_key":"764624"}},{"flight":{"flightno":"RYR63BC","timestamp":"2011-04-24 05:48:02","route":"EGNX-LEGE","primary_key":"761726"}},{"flight":{"flightno":"RYR7PX","timestamp":"2011-04-23 19:39:03" 

格式化样本:

{ 
    "flights":[ 
     { 
     "flight":{ 
      "flightno":"RYR54WP", 
      "timestamp":"2011-04-26 12:13:04", 
      "route":"EGNX-LEAL", 
      "primary_key":"836453" 
     } 
     }, 
     { 
     "flight":{ 
      "flightno":"RYR24LU", 
      "timestamp":"2011-04-26 09:14:03", 
      "route":"EVRA-EGNX", 
      "primary_key":"831318" 
     } 
     } 
    ] 
} 

编辑2:

因此,这里是 “niceDate”,是造成减速!

-(NSString *)niceDate:(NSString *)oldDate{ 
    NSDateFormatter *formatter = [[[NSDateFormatter alloc] init]autorelease]; 
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 
    NSDate *sourceDate = [formatter dateFromString:oldDate]; 
    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; 
    [dateFormatter setDateStyle:NSDateFormatterFullStyle]; 
    [dateFormatter setTimeStyle:NSDateFormatterLongStyle]; 
    NSString *timeString = [dateFormatter stringFromDate:sourceDate]; 
    return [NSString stringWithFormat:@"%@",timeString]; 
} 
+0

您是否提供了一些性能分析时间戳来查看哪一部分花费最多时间? – 2011-04-26 12:16:45

+0

增加了一些时间戳,但不能真正在循环中插入一些没有真正放慢速度的内容! – 2011-04-26 12:25:13

+0

我们在谈论多少次迭代?你可以输入一些日志代码,只是看看你的循环在第一次10/50/100迭代中的效果如何。也许由于某种原因,性能会下降? – 2011-04-26 12:30:23

回答

3

浮现在脑海中有些事情:

NSArray *flights = [deserializedData valueForKeyPath:@"flights.flight"]; 

你需要使用KVC?你的JSON数据的结构是什么?

ArchiveFlight *aFlight = [[ArchiveFlight alloc] initWithFlightno:[flight objectForKey:@"flightno"] route:[flight objectForKey:@"route"]]; 
aFlight.flightID = [flight objectForKey:@"primary_key"]; 
aFlight.timeStamp = [aFlight niceDate:[flight objectForKey:@"timestamp"]]; 

你总是创建ArchiveFlight实例和解析时间戳...

if (![lastFlightno isEqualToString:aFlight.flightno]) { 
     [localArray addObject:aFlight]; 
    } 

...即使你没有这样做,所有的时间。取决于你有多少重复的flightnos,这可能会引起显着的差异。

为什么不读[flight objectForKey:@"flightno"],将它与lastFlightno进行比较,当且仅当它们不同时,创建一个实例,将其添加到数组中并释放它?


编辑:请尝试以下KVC-免费代码:

NSArray *flights = [deserializedData objectForKey:@"flights"]; 
NSMutableArray *localArray = [[NSMutableArray alloc] init ]; 
NSString *lastFlightno [email protected]""; 

for (NSDictionary *flightWrapper in flights) { 
    NSDictionary *flight = [flightWrapper objectForKey:@"flight"]; 
    NSString *flightno = [flight objectForKey:@"flightno"]; 

    if (! [flightno isEqual:lastFlightno]) { 
     // create instance, add it to the array, release the instance 
    } 
} 

编辑:你创建和(自动)发布这个方法里面NSDateFormatter两个实例。一般情况下,这样可以,但是由于执行次数大于1K,因此需要考虑两个因素:a)创建/使用/释放这两个实例的次数大于1K次,实际上,如果没有两次,则会出现b )你应该在你的循环中使用一个autorelease池。

您应该使此方法成为类方法(或函数),因为它不依赖于该类的实例的状态。您的格式化程序将是类(静态)变量。例如:

@implementation ArchiveFlight 

static NSDateFormatter *formatter1; // choose better names! 
static NSDateFormatter *formatter2; 

+ (void)initialize { 
    if (self == [ArchiveFlight class]) { 
     formatter1 = [[NSDateFormatter alloc] init]; 
     [formatter1 setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 

     formatter2 = [[NSDateFormatter alloc] init]; 
     [formatter2 setDateStyle:NSDateFormatterFullStyle]; 
     [formatter2 setTimeStyle:NSDateFormatterLongStyle]; 
    } 
} 

+ (NSString *)niceDate:(NSString *)oldDate { 
    NSDate *sourceDate = [formatter1 dateFromString:oldDate]; 
    NSString *timeString = [formatter2 stringFromDate:sourceDate]; 
    return timeString; 
    // why +stringWithFormat:? It’s not necessary! 
    // return [NSString stringWithFormat:@"%@",timeString]; 
} 

这修复项),但你因为你使用回报Cocoa方法自动释放对象真正应该使用自动释放池的循环内。通过为循环的每次迭代使用自动释放池,可以减少代码的内存占用量 - 尽管如此,也可能会降低性能。我建议你尝试使用和不使用内部自动释放池。

for (NSDictionary *flightWrapper in flights) { 
    NSAutoreleasePool *pool = [NSAutoreleasePool new]; 

    … 

    [pool drain]; 
} 
+0

谢谢,我已经将JSON的样本添加到了原始问题中....没有多少重复的flightno,但是确实有一个很好的简单修复,确实会刮掉一点点! 我认为它的大部分是在KVC上,有没有另一种方式? – 2011-04-26 12:43:02

+0

@Lee我已经更新了答案。 – 2011-04-26 12:49:37

+0

谢谢,这是一个更快一点。 1.2秒现在做循环语句。仍然有点太长,无法理解为什么当通过网络和JSONKit的请求做到这一切非常快!混乱! – 2011-04-26 13:03:00