Вопрос

Мне нужно определить, включен ли объект в основные данные о отношениях (что является NSSet), и я пытаюсь решить, какое из двух решений лучше:

Решение 1)

if ([managedObject.items containsObject:itemOfInterest])
    return …

Решение 2)

for (NSManagedObject *item in managedObject.items)
    if ([item == itemOfInterest])
        return …

Решение 1 более краткое, но ref ref Class NSSet говорит, что быстрое перечисление работает лучше, чем объект -энтузиатор NSSet. Он также работает лучше, чем содержит?

Это было полезно?

Решение

Я всегда ходил на вариант 1.

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

Другие советы

Ни один. Вы должны использовать NSFetchRequest с предикатом. Ваши шаблоны могут случайно обвинить все отношения, что очень дорого и не требуется, чтобы проверить, содержит ли он один объект. Есть способы быть осторожными и не винить все отношения, но это хрупкие (небольшие изменения в вашем поиске приводят к огромным изменениям в производительности), и поэтому лучше иметь привычку использовать NSFetchRequest а не коллекция для поиска. Я люблю устанавливать свой fetchLimit 1 в этих случаях, так что, как только он его найдет, он перестает искать.

Для удобства вы можете создать -containsFoo: Метод на вашем управляемом объекте, чтобы вам не приходилось писать логику извлечения повсюду.

Ваши два решения выше тонко отличаются. Первый проверяет, есть ли объект в коллекции, который isEqual: к itemOfInterest. Анкет Ваше второе решение проверяет, есть ли объект в коллекции в том же месте памяти, что и itemOfInterest. Анкет Для объектов с пользовательскими isEqual: Логика, они могут вернуть разные результаты. Это означает, что решение 2 может быть немного быстрее для неточных коллекций данных, но это потому, что вы на самом деле тестируете другое дело, а не из-за перечисления объектов. (В действительности это верно только для небольших коллекций; см. Ниже.)

Почему вы считаете, что решение 1 использует -objectEnumerator?

Как указывает @James Raybould, вы, как правило, не должны пытаться переписать встроенные методы по соображениям производительности. Если isEqual: Версия решения 2 была быстрее, чем решение 1, разве вы не думаете, что Apple внедрила бы -containsObject: Используя код в решении 2?

На самом деле, основной CFSet реализуется как хэш, поэтому проверка на содержание является логарифмической, а не линейной. Вообще говоря, для больших наборов с разумными хэш -функциями решение 1 будет быстрее. Смотрите код для него в Cfset.c. Анкет Ищу CFSetContainsValue(). Анкет Конечно, реализация CFSET не гарантированно остается прежней, но она полезна для понимания того, как проблемы производительности обычно решаются в какао.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top