此代码块是一种创建数组以供其他多个类使用的方法。输入是从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)。

07-24 09:36