web-dev-qa-db-ja.com

NSDictionaryに特定のキーが含まれているかどうかを確認する方法はどれが速いですか?

NSDictionaryにキーが存在するかどうかをテストするには、次の2つの方法があります。

BOOL containsKey = [[dictionary allKeys] containsObject:foo];

BOOL containsKey = ([dictionary objectForKey:foo] != nil);

どの方法が速いのか、そしてその理由は?

32
alfwatt

ハッシュルックアップは、一般に、すべての辞書キーを調べて、それらから配列を作成し(メモリ割り当ては比較的高価です)、配列を検索する(配列が並べ替えられていないため、バイナリ検索にすることさえできない)よりも高速である必要があります。 。

ただし、科学のために、各スタイルを100万回実行するだけの2つの実行可能ファイルを作成し、それらの時間を計測しました。

AllKeysの場合:

real    0m4.185s
user    0m3.890s
sys     0m0.252s

ObjectForKeyの場合:

real    0m0.396s
user    0m0.189s
sys     0m0.029s

明らかに、辞書のサイズ、allKeysの戻り値のキャッシュなど、さまざまな要因がこれに影響を与える可能性があります。ただし、配列検索が辞書検索よりも高速である場合はないと思います。

68
Chuck

AllKeys配列の要求がどのように高速になるかわかりません。そうでない場合、NSDictionaryは少なくとも内部で同等の処理を実行します。

編集:たとえば、キーのallKeysメソッドでは時間がかかるが、isEqual:メソッドでは時間がかからない場合は、hashメソッドの方が高速になるケースを作成できると思います。また、それらが交換されるNSDictionaryのクレイジーな実装に交換することもできます(NSDictionaryは抽象的であるため)。

6
Jesse Rusak

このようなパフォーマンスの質問について考えるときは、Foundationデータクラスが、格納するオブジェクトの数に応じて、基になるデータ構造を交換することに注意してください。たとえば、小さなNSArrayは、実際には、特定のサイズに達するまで、ストレージにハッシュテーブルを使用すると思います。

2