Выполнить арифметику для двух NSArray по компонентам мудрым способом? - PullRequest
0 голосов
/ 27 января 2012

У меня есть два объекта NSArray, и я хочу добавить два массива вместе по компонентам таким образом, чтобы int в array1 по индексу i был добавлен к int в массиве 2 по индексу i с результатом, добавленным в новый массив,Есть ли более быстрый способ сделать это, чем при использовании стандартных методов for (int i = 0; i <[array1 count]; i ++)?Например, вы можете использовать массивы c, быстрое перечисление, блоки?Я особенно заинтересован, потому что я хотел бы добавить x количество массивов, содержащих большое количество объектов.Мой текущий код выглядит следующим образом: </p>

    NSArray *array1 = [NSArray arrayWithObjects:
                   [NSNumber numberWithInt:1],
                   [NSNumber numberWithInt:2],
                   [NSNumber numberWithInt:3],
                   [NSNumber numberWithInt:4],
                   nil];

NSArray *array2 = [NSArray arrayWithObjects:
                   [NSNumber numberWithInt:10],
                   [NSNumber numberWithInt:20],
                   [NSNumber numberWithInt:30],
                   [NSNumber numberWithInt:40],
                   nil];

NSMutableArray *resultArray = [[NSMutableArray alloc] initWithCapacity:[array1 count]];

for (int i=0; i<[array1 count]; i++) {
    int result = [[array1 objectAtIndex:i] intValue] + [[array2 objectAtIndex:i] intValue];
    [resultArray addObject:[NSNumber numberWithInt:result]];                                
} 

Спасибо, я благодарен за любые комментарии.

Ответы [ 2 ]

1 голос
/ 27 января 2012

Вот пример того, как сделать это с блоками и одновременным перечислением:

NSArray *array1 = [NSArray arrayWithObjects:
                   [NSNumber numberWithInt:1],
                   [NSNumber numberWithInt:2],
                   [NSNumber numberWithInt:3],
                   [NSNumber numberWithInt:4],
                   nil];

NSArray *array2 = [NSArray arrayWithObjects:
                   [NSNumber numberWithInt:10],
                   [NSNumber numberWithInt:20],
                   [NSNumber numberWithInt:30],
                   [NSNumber numberWithInt:40],
                   nil];

NSMutableArray *resultArray = [[NSMutableArray alloc] initWithCapacity:[array1 count]];
for (int i=0; i<[array1 count]; i++) {
    [resultArray addObject:[NSNull null]];
}

dispatch_queue_t resultArrayQueue = dispatch_queue_create("com.yourcompany.appname.resultsArrayQueue", DISPATCH_QUEUE_SERIAL);

[array1 enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    int num1 = [(NSNumber *)obj intValue];
    int num2 = [[array2 objectAtIndex:idx] intValue];
    NSNumber *result = [NSNumber numberWithInt:(num1 + num2)];
    dispatch_async(resultArrayQueue, ^{
        [resultArray replaceObjectAtIndex:idx withObject:result];
    });
}];

NSLog(@"Result array: %@", resultArray);

Чтобы определить, быстрее это или нет, потребуется профилирование.Я догадываюсь, что это не намного быстрее и даже может быть медленнее из-за (относительно небольших, но все еще существующих) накладных расходов на отправку GCD.Однако для более сложных вычислений, чем для простого сложения, это дает вам представление о том, как использовать параллельное перечисление, чтобы легко что-то делать с каждым элементом массива многоядерным способом.

Если у вас было х числомассивы в массиве верхнего уровня (как описано в вашем комментарии), вы можете заменить -enumerateObjectsWithOptions: usingBlock: call чем-то вроде этого:

dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(numberOfItemsInEachArray, globalQueue, ^(size_t idx) {
    NSInteger sum = 0;
    for (NSArray *array in parentArray) {
        sum += [[array objectAtIndex:idx] integerValue];
    }

    NSNumber *result = [NSNumber numberWithInteger:sum];
    dispatch_async(resultArrayQueue, ^{
        [resultArray replaceObjectAtIndex:idx withObject:result];
    });
});

dispatch_apply() - это функция Grand Central Dispatch, которая простозапускает блок кода указанное количество раз.Поскольку мы говорим использовать глобальную параллельную очередь, которую мы получили с dispatch_get_global_queue(), он может одновременно выполнять различные вызовы блока, обеспечивая (возможное) повышение производительности на многоядерных машинах.Как и в большинстве задач программирования, существует множество других способов решения этой проблемы.Это только то, что пришло мне в голову.

0 голосов
/ 27 января 2012

Вы действительно не можете обойти оба массива хотя бы один раз, если хотите подвести их итог.Тем не менее, вы можете посмотреть на массив как матрицу.В этом контексте есть несколько очень быстрых матричных арифметических алгоритмов или библиотек, которые вы можете использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...