Question

Je dois déterminer si un objet est inclus dans une base de données à plusieurs rapports (qui est un NSSet), et je suis en train de décider lequel des deux solutions est mieux:

Solution 1)

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

Solution 2)

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

Solution 1 est plus concis, mais la classe NSSet Ref dit énumération rapide de effectue mieux que la objectEnumerator de NSSet. Est-il effectuer aussi mieux que containsObject?

Était-ce utile?

La solution

Je toujours aller pour l'option 1.

Son plus concis, je peux dire exactement ce que vous essayez de faire avec le code et les chances sont que le containsObject contient quelques Optimisations assez astucieuses.

Autres conseils

Ni. Vous devez utiliser un NSFetchRequest avec un prédicat. Vos modèles peuvent accidentellement défaut l'ensemble des relations, ce qui est très cher et pas besoin juste pour vérifier si elle contient un objet. Il y a plusieurs façons d'être prudent et ne pas reprocher à la relation ensemble, mais il est fragile (petits changements à votre recherche conduisent à d'énormes changements dans la performance) et il est donc préférable d'être l'habitude d'utiliser NSFetchRequest plutôt que la collection pour la recherche. Je tiens à mettre mon fetchLimit à 1 dans ces cas, donc une fois qu'il trouve, il cesse de chercher.

Pour plus de commodité, vous voudrez peut-être créer une méthode -containsFoo: sur votre objet géré de sorte que vous n'avez pas à écrire le tout sur la place logique fetch.

Vos deux solutions ci-dessus sont subtilement différents. Les premiers on teste s'il y a un objet dans la collection qui isEqual: à itemOfInterest. Votre deuxième solution teste si un objet se trouve dans la collection au même endroit de mémoire itemOfInterest. Pour les objets avec la logique isEqual: personnalisée, ceux-ci peuvent retourner des résultats différents. Cela signifie que la solution 2 pourrait être un peu plus rapide pour les collections de données non essentielles, mais il est parce que vous testez en fait une chose différente, non pas à cause de l'énumération des objets. (En réalité, cela n'est vrai pour les petites collections;. Voir ci-dessous)

Pourquoi croyez-vous que la solution 1 utilisations -objectEnumerator?

Comme le souligne Raybould @ James, vous devriez généralement pas essayer de réécrire les méthodes intégrées pour des raisons de performance. Si une version isEqual: de la solution 2 était plus rapide que la solution 1, ne pensez-vous pas Apple aurait mis en œuvre -containsObject: utilisant le code en solution 2?

En réalité, le CFSet sous-jacente est implémenté comme un hachage, donc la vérification de confinement est logarithmique plutôt que linéaire. D'une manière générale, pour les grands ensembles avec des fonctions de hachage raisonnables, solution 1 sera plus rapide. Voir le code pour en CFSet.c . Cherchez CFSetContainsValue(). La mise en œuvre de cfset n'est pas garanti de rester le même, bien sûr, mais il est utile pour comprendre comment les problèmes de performances sont généralement traitées dans le cacao.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top