2011-04-26 5 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의

타임 스탬프 ... json으로의

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 

샘플 ...

{"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

어떤 프로파일 링 타임 스탬프를 사용하여 어떤 부분이 가장 오래 걸리는지 확인 했습니까? –

+0

일부 타임 스탬프가 추가되었지만 실제로는 느려지 지 않으면 루프 내에 일부를 삽입 할 수 없습니다! –

+0

얼마나 많은 반복 작업을하는 중입니까? 로깅 코드를 입력하고 루프가 처음 10/50/100 반복을 수행하는 방법을 확인할 수 있습니다. 어쩌면 성능이 저하 되었기 때문일 수 있습니다. –

답변

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]; 
    } 

... 당신은 모든 시간을 할 필요가 없습니다에도 불구하고. 얼마나 많은 사람들이 반복했는지에 따라, 이것은 눈에 띄는 차이를 만들 수 있습니다.

[flight objectForKey:@"flightno"]을 읽지 않는 이유는 lastFlightno과 비교하고, 다른 경우에만 인스턴스를 만들고 배열에 추가 한 다음 놓으십시오.


편집 : 당신은 생성하고이 방법 안에 NSDateFormatter의 두 인스턴스를 해제 (자동)하고 :

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 
    } 
} 

편집 : 다음 KVC없는 코드를 사용해보십시오. 일반적으로 이것은 괜찮을 것이지만,> 1K 번 실행되기 때문에 두 가지 고려 사항이 있습니다 : a) 두 인스턴스를 생성/사용/해제하고 있습니다.> 실제로 1K 번, 두 개가없는 경우, b) 루프에서 자동 복구 풀을 사용해야합니다.

이 메서드는 해당 클래스의 인스턴스 상태에 종속되지 않으므로 클래스 메서드 또는 함수로 만들어야합니다. 포맷터는 클래스 (정적) 변수입니다.예를 들어 :

@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]; 
} 

이 항목 A)를 수정하지만 당신은 반환을 사용하고있는 코코아 방법은 객체를 오토 릴리즈 때문에 정말 루프 내에서 오토 릴리즈 풀을 사용합니다. 루프를 반복 할 때마다 자동 릴리스 풀을 사용하면 코드의 메모리 사용량을 줄일 수 있습니다. 의 경우까지도 성능이 저하 될 수 있습니다. 내적 autorelease 풀을 사용하거나 사용하지 않고 시도해 보시기 바랍니다.

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

    … 

    [pool drain]; 
} 
+0

감사합니다. 원본 질문에 JSON 예제를 추가했습니다. flightno 's는 많이 반복되지 않지만 좋은 간단한 수정이 실제로 거기에서 조금씩 면도됩니다! 나는 그것의 대부분이 KVC에 있다고 생각하는데, 다른 방법이 있습니까? –

+0

@Lee 답변을 업데이트했습니다. –

+0

고마워, 조금 빨라. 1.2 초 루프 문장을 할 수 있습니다. 아직 조금 길어서 네트워크와 JSONKit을 통해 요청이 모두 매우 신속하게 처리되는 이유를 이해할 수 없습니다! 혼란스러워! –