2012-02-07 30 views
0

私はPlaceオブジェクトの配列を持っています。それぞれのPlaceオブジェクトには、両方ともnamecodeというプロパティがあります。各Placeオブジェクトには既にcodeが含まれていますが、サーバーからnameプロパティを検索する必要があります。私は2つの配列を返します:1つは名前、他のコードを含みます。これらの配列は、nameArrayのあるインデックスのnamecodeArrayの同じインデックスのcodeと正確に一致するように順序付けられています。文字列を比較/設定する最速の方法

私は、そのPlaceためcodeプロパティはcodeArrayにおける現在のインデックスと同じであるかどうかをチェックする、Placeオブジェクトの配列をループされています。もしそうであれば、私はnameArrayで同じインデックスを使用して、そのPlacenameを設定します。

for(int i = 0; i < [placesArray count]; i++) 
{ 
    for(int j = 0; j < [codeArray count]; j++) { 

     if([[[placesArray objectAtIndex:i] code] isEqualToString:[codeArray objectAtIndex:j]]) { 
      [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]]; 
     } 
    } 
} 

これは動作しますが、ひどく速くない - それはをループに1000の+の場所で30秒かかることがあります。

速い方法がありますか?あなたは、パフォーマンスを最適化しようとしていると同じように、いつでもあなたがNSArrayの-containsObject

if ([myarray containsObject:myObject]) { 
    // ... 
} 

答えて

1

のために使用することができます

+0

私はすでにこれをプロファイリングして、 'isEqualToString:'がたくさん呼ばれているのを見ました。私はあなたのソリューションを試してみたところ、パフォーマンスが〜96%向上しました。あなたはアンドリューを揺する。 – colby

0

は、あなたがボトルネックが実際にある場所を見つけるために楽器を使用してコードをプロファイリングする必要があります。つまり、nameArrayの各名前のplacesArrayをループし、文字列の比較を行うことはかなり非効率的です。

どうやってこのようなことができますか?辞書にそのコードによって各場所を探し

NSMutableDictionary *placesByCode = [NSMutableDictionary dictionaryWithCapacity:[placesArray count]]; 
for (Place *aPlace in placesArray) { 
    [dictionary setObject:aPlace forKey:aPlace.code]; 
} 

NSMutableDictionary *namesByCode = [NSMutableDictionary dictionaryWithCapacity:[namesArray count]]; 
for (int i=0; i<[namesArray count]; i++) { 
    NSString *name = [namesArray objectAtIndex:i]; 
    NSString *code = [codeArray objectAtIndex:i]; 
    [namesByCode setObject:name forKey:code]; 
} 

for (NSString *code in namesByCode) { 
    Place *place = [placesByCode objectForKey:code]; 
    place.name = [namesByCode objectForKey:namesByCode]; 
} 

はかなり速く、手動でそれぞれの名前のための全体の場所の配列をループするよりもする必要があります。

+0

私は 'containsObject:'を使うように自分のコードを修正し、性能が〜60%向上しました。彼の解決策が〜96%増加して以来、私は正しいとAndrew'sをマークしました。 – colby

0

内側のループでbreak文を使用してみてください。この方法では、毎回ループ全体をループする必要はありません。

for(int i = 0; i < [placesArray count]; i++) 
{ 
    for(int j = 0; j < [codeArray count]; j++) { 

     if([[[placesArray objectAtIndex:i] code] isEqualToString:[codeArray objectAtIndex:j]]) { 
      [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]]; 
      break; 
     } 
    } 
} 

さらに多くの結果が得られれば、2番目の配列を小さくすることもできます。それはあなたにもっと多くのメモリを必要としますが、1000文字列はとにかくあまりありません。

NSMutableArray * tempCodeArray = [NSMutableArray arrayWithArray:codeArray]; 
for(int i = 0; i < [placesArray count]; i++) 
{ 
    for(int j = 0; j < [tempCodeArray count]; j++) { 

     if([[[placesArray objectAtIndex:i] code] isEqualToString:[tempCodeArray objectAtIndex:j]]) { 
      [[placesArray objectAtIndex:i] setName:[nameArray objectAtIndex:j]]; 
      [tempCodeArray removeObjectAtIndex:j]; 
      break; 
     } 
    } 
} 
0

問題は、それが(N N *)Oがかかりますforループを組み込みます、配列のカウントではなかったとアンドリューのソリューションでは、それだけではO(n)+ O(N)+ O(ですn)+辞書にあるキーのオブジェクトを見つけるために取るものは何でも、ハッシュテーブルルックアップにあると思いますが、それは本当に速いです。

コルビー、あなたはおそらくアンドリューの解決策で大丈夫でしょう。それでもパフォーマンスを向上させたい場合は、まず配列をソートしてからルックアップを行うことをお勧めします。

これが役に立ちます。