どちらが良いのですか、NSSetのcontainSoBjectまたはfast enum?
-
27-10-2019 - |
質問
オブジェクトがコアデータとマンスの関係(NSSET)に含まれているかどうかを判断する必要があります。2つのソリューションのどれが優れているかを決定しようとしています。
解決策1)
if ([managedObject.items containsObject:itemOfInterest])
return …
解決策2)
for (NSManagedObject *item in managedObject.items)
if ([item == itemOfInterest])
return …
ソリューション1はより簡潔ですが、NSSETクラスREFは、高速列挙がNSSETのオブジェクトネイマレーターよりも優れたパフォーマンスを発揮すると述べています。また、containtobjectよりも優れたパフォーマンスもありますか?
解決
私はいつもオプション1に行きます。
より簡潔に言えば、コードで何をしようとしているのかを正確に伝えることができます。
他のヒント
ない。を使用する必要があります NSFetchRequest
述語で。パターンは誤って関係全体に障害を妨げる可能性があります。これは非常に高価であり、1つのオブジェクトが含まれているかどうかを確認するためだけに必要ではありません。関係全体に違反しないように注意する方法がありますが、それは壊れやすいです(検索の小さな変化はパフォーマンスの大きな変化につながります)。 NSFetchRequest
検索のためのコレクションではなく。私は自分を設定するのが好きです fetchLimit
これらの場合に1に、それが見つかると、見た目が停止します。
便利なため、aを作成することをお勧めします -containsFoo:
管理されたオブジェクトのメソッドでは、フェッチロジックをあちこちに記述する必要がないようにします。
上記の2つのソリューションは微妙に異なります。最初のものは、コレクションにオブジェクトがあるかどうかをテストします isEqual:
に itemOfInterest
. 。 2番目のソリューションは、コレクションに同じメモリの場所にオブジェクトがあるかどうかをテストします itemOfInterest
. 。カスタムを備えたオブジェクト用 isEqual:
ロジック、これらは異なる結果を返すことができます。これは、ソリューション2が非コアデータコレクションではわずかに高速である可能性があることを意味しますが、オブジェクトの列挙ではなく、実際に別のものをテストしているためです。 (実際には、これは小さなコレクションにのみ当てはまります。以下を参照してください。)
なぜソリューション1が使用すると信じているのですか -objectEnumerator
?
@james Raybouldが指摘しているように、通常、パフォーマンス上の理由で組み込みの方法を書き直そうとしないでください。もし isEqual:
ソリューション2のバージョンはソリューション1よりも高速でした、Appleが実装したとは思わないでしょうか -containsObject:
ソリューション2でコードを使用しますか?
現実には、根底にある CFSet
ハッシュとして実装されるため、封じ込めのチェックは線形ではなく対数です。一般的に言えば、合理的なハッシュ関数を備えた大きなセットの場合、ソリューション1はより速くなります。そのコードを参照してください cfset.c. 。探す CFSetContainsValue()
. 。もちろん、CFSetの実装は同じままであることは保証されていませんが、パフォーマンスの懸念がCoCoA内で一般的にどのように対処されるかを理解するのに役立ちます。