gpt4 book ai didi

ios - 使用 NSDictionary 元素缓慢创建 NSMutableArray

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:37:32 24 4
gpt4 key购买 nike

这段代码是一个创建数组供多个其他类使用的方法。输入是一个来自 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 )。

关于ios - 使用 NSDictionary 元素缓慢创建 NSMutableArray,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27277899/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com