Самый быстрый способ сравнить / установить строки - PullRequest
0 голосов
/ 07 февраля 2012

У меня есть массив Place объектов. Каждый объект Place имеет свойства name и code, обе строки. Каждый объект Place уже имеет code, но мне нужно найти свойство name на сервере. Я получаю обратно 2 массива: один содержит имя, другой коды. Эти массивы упорядочены так, что name в некотором индексе в nameArray точно соответствует code в том же индексе codeArray.

Я просматривал массив объектов Place, а затем проверял, совпадает ли свойство code для этого Place с текущим индексом в codeArray. Если это так, я устанавливаю name этого Place, используя тот же индекс в nameArray:

for(int i = 0; i < [placesArray count]; i++)
{
    for(int j = 0; j < [codeArray count]; j++) {

       if([[[placesArray objectAtIndex:i] code] isEqualToString:[codeArray objectAtIndex:j]]) {   
            [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]];
       }
    }
}

Это работает, но не очень быстро - это может занять 30 секунд с 1000+ местами для прохождения.

Есть ли более быстрый способ?

Ответы [ 4 ]

1 голос
/ 07 февраля 2012

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

Как насчет этого?

NSMutableDictionary *placesByCode = [NSMutableDictionary dictionaryWithCapacity:[placesArray count]];
for (Place *aPlace in placesArray) {
    [dictionary setObject:aPlace forKey:aPlace.code];
}

NSMutableDictionary *namesByCode = [NSMutableDictionary dictionaryWithCapacity:[namesArray count]];
for (int i=0; i<[namesArray count]; i++) {
    NSString *name = [namesArray objectAtIndex:i];
    NSString *code = [codeArray objectAtIndex:i];
    [namesByCode setObject:name forKey:code];
}

for (NSString *code in namesByCode) {
    Place *place = [placesByCode objectForKey:code];
    place.name = [namesByCode objectForKey:namesByCode];
}

Поиск каждого места по его кодув словаре должно быть немного быстрее, чем вручную перебирать весь массив мест для каждого имени.

0 голосов
/ 08 февраля 2012

Проблема заключалась не в подсчете массива, а во встроенном цикле for, который будет принимать O (n * n), а в решении Эндрю только O (n) + O (n) + O (n) + как угодно чтобы найти объект ключа в словаре, который, я думаю, был бы в поиске хеш-таблицы, и это действительно быстро.

Колби, вы, вероятно, будете в порядке с решением Эндрю. Если вы все еще хотите улучшить производительность, то хорошей идеей будет сначала отсортировать массив, а затем выполнить поиск.

Надеюсь, это поможет.

0 голосов
/ 07 февраля 2012

Попробуйте использовать оператор break во внутреннем цикле. Таким образом, вам не нужно каждый раз проходить весь цикл.

for(int i = 0; i < [placesArray count]; i++)
{
    for(int j = 0; j < [codeArray count]; j++) {

       if([[[placesArray objectAtIndex:i] code] isEqualToString:[codeArray objectAtIndex:j]]) {   
            [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]];
            break;
       }
    }
}

Вы также можете уменьшить размер второго массива, если найдете больше результатов. Это будет стоить вам больше памяти, но 1000 строк не так много.

NSMutableArray * tempCodeArray = [NSMutableArray arrayWithArray:codeArray];
for(int i = 0; i < [placesArray count]; i++)
{
    for(int j = 0; j < [tempCodeArray count]; j++) {

       if([[[placesArray objectAtIndex:i] code] isEqualToString:[tempCodeArray objectAtIndex:j]]) {   
            [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]];
            [tempCodeArray removeObjectAtIndex:j];
            break;
       }
    }
}
0 голосов
/ 07 февраля 2012

Вы можете использовать для NSArray -containsObject

if ([myarray containsObject:myObject]) {
    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...