5

オブジェクトがCoreDataと多の関係(NSSet)に含まれているかどうかを判断する必要があり、2つのソリューションのどちらが優れているかを判断しようとしています。

解決策1)

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

解決策2)

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

解決策1はより簡潔ですが、NSSet Class Refによると、高速列挙はNSSetのobjectEnumeratorよりも優れています。また、containsObjectよりもパフォーマンスが優れていますか?

4

2 に答える 2

20

ない。NSFetchRequest述語とともにを使用する必要があります。パターンが誤って関係全体に障害を起こす可能性があります。これは非常にコストがかかり、1つのオブジェクトが含まれているかどうかを確認するためだけに必要なわけではありません。注意して関係全体を損なうことのないようにする方法はありますが、それは壊れやすいため(検索に小さな変更を加えると、パフォーマンスが大幅に変化します)、NSFetchRequest検索用のコレクションよりも使用する習慣を身に付ける方がよいでしょう。このような場合は1に設定するのが好きなfetchLimitので、検出されると検索を停止します。

便宜上、-containsFoo:管理対象オブジェクトにメソッドを作成して、フェッチロジックをあちこちに作成する必要がないようにすることができます。

上記の2つのソリューションは、微妙に異なります。最初のものは、コレクションにオブジェクトがあるかどうかをテストisEqual:itemOfInterestます。2番目のソリューションは、コレクション内のと同じメモリ位置にオブジェクトがあるかどうかをテストしますitemOfInterest。カスタムisEqual:ロジックを持つオブジェクトの場合、これらは異なる結果を返す可能性があります。これは、ソリューション2がコア以外のデータ収集に対してわずかに高速である可能性があることを意味しますが、これは、オブジェクトの列挙ではなく、実際に別のものをテストしているためです。(実際には、これは小さなコレクションにのみ当てはまります。以下を参照してください。)

ソリューション1が使用していると思うのはなぜ-objectEnumeratorですか?

@James Raybouldが指摘しているように、パフォーマンス上の理由から、通常、組み込みメソッドを書き直そうとしないでください。ソリューション2のisEqual:バージョンがソリューション1よりも高速だったとしたら、Appleは-containsObject:ソリューション2のコードを使用して実装したと思いませんか?

実際には、原資産CFSetはハッシュとして実装されているため、包含のチェックは線形ではなく対数です。一般的に、妥当なハッシュ関数を持つ大規模なセットの場合、ソリューション1の方が高速です。CFSet.cのコードを参照してください。を探しCFSetContainsValue()ます。もちろん、CFSetの実装が同じであるとは限りませんが、Cocoa内でパフォーマンスの問題が一般的にどのように対処されているかを理解するのに役立ちます。

于 2011-03-18T19:41:53.633 に答える
5

私はいつもオプション1に行きます。

もっと簡潔に言えば、コードで何をしようとしているのかを正確に知ることができ、containsObjectにはかなり気の利いた最適化が含まれている可能性があります。

于 2011-03-18T19:15:09.823 に答える