此代码块是一种创建数组以供其他多个类使用的方法。输入是从CoreData获取的数组,其类型为NSDictionaryResultType。
其中3个字段是我需要分成数组的字符串,因此是componentsSeparatedByString。
生成的数组_dataProductionArray很好用---但是---这块代码需要完整的5秒来处理大约32,000条记录。
指出导致这种性能下降的明显错误的任何帮助将不胜感激!
NSMutableArray *dataArray = [NSMutableArray array];
int j = 0;
int maxNumMonths = 0;
for (id obj in _dictionaries) {
if ([_dictionaries[j] [@"month"] length] >0 ) {
// get production values
NSArray *aItems = [_dictionaries[j] [@"prodA"] componentsSeparatedByString:@","];
NSArray *bItems = [_dictionaries[j] [@"prodB"] componentsSeparatedByString:@","];
NSArray *monthItems = [_dictionaries[j] [@"month"] componentsSeparatedByString:@","];
NSMutableArray *productionAArray = [NSMutableArray array];
NSMutableArray *productionBArray = [NSMutableArray array];
int monthLoop = 1;
for (NSNumber *month in monthItems) {
if (monthLoop <= MONTHS_OF_PRODUCTION) {
if ([month intValue] == monthLoop) {
[productionAArray addObject:[aItems objectAtIndex:monthLoop-1]];
[productionBArray addObject:[bItems objectAtIndex:monthLoop-1]];
productionCount ++;
if (monthLoop > maxNumMonths)
maxNumMonths = monthLoop;
}
}
monthLoop++;
}
NSDictionary *arrayItem = @{@"name":_dictionaries[j] [@"name"],
@"type":[NSString stringWithFormat:@"%@",_dictionaries[j] [@"type"]],
@"height":[NSString stringWithFormat:@"%@",_dictionaries[j] [@"height"]],
@"aArray":productionAArray,
@"bArray":productionBArray,
};
[dataArray addObject:arrayItem];
}
j++;
}
_dataProductionArray = [NSArray arrayWithArray:dataArray];
最佳答案
我可以看到您可以在循环中执行的一些优化,但是我不确定这些优化有多大帮助(尤其是如果编译器仍在进行优化)。根本问题是32k是很多迭代。
您一次需要所有32k结果吗?通过执行lazily这项工作,您可以极大地改善用户体验,因为UI需要转换后的记录。
这种方法将使dataProductionArray成为可变字典,并由NSNumber索引建立索引。然后,而不是...
// replace this
self.dataProductionArray[128];
// with this
[self dataProductionAtIndex:@128];
这个新的getter方法像这样...懒惰地调用您编写的代码...
- (id)dataProductionAtIndex:(NSNumber *)index {
// replace dataProductionArray with dataProductionDictionary
id result = self.dataProductionDictionary[index];
if (!result) {
result = [self getDataAt:index];
self.dataProductionDictionary[index] = result;
}
return result;
}
然后
getDataAt:
是您发布的代码的简单重构,除了循环32k元素外,它只对传入的一个索引起作用。- (id)getDataAt:(NSNumber *)index {
int j = [index intValue];
// no loop, just skip to iteration j
NSArray *aItems = [_dictionaries[j] [@"prodA"] componentsSeparatedByString:@","];
NSArray *bItems = [_dictionaries[j] [@"prodB"] componentsSeparatedByString:@","];
// and so on, then at the end, don't save arrayItem, just return it
NSDictionary *arrayItem = @{@"name":_dictionaries[j] [@"name"],
@"type":[NSString stringWithFormat:@"%@",_dictionaries[j] [@"type"]],
@"height":[NSString stringWithFormat:@"%@",_dictionaries[j] [@"height"]],
@"aArray":productionAArray,
@"bArray":productionBArray,
};
return arrayItem;
}
PS-可变字典是用于延迟评估的良好数据结构。复杂性的下一个层次是NSCache,它充当可变字典,并且还管理内存(class ref here)。