この問題は解決されました。http://en.wikipedia.org/wiki/Knuth_shuffle
templatetypedefもこれについてコメントしました。
フィッシャー-イェーツシャッフルamutableCopy
は非常に高速で、ランダム化が優れています。小さな配列(10要素)の場合、以下に実装されているように、提案はフィッシャー-イェーツシャッフルよりもわずかに高速です。大きな配列(1000000要素)の場合、Fisher_Yatesはあなたの配列の4倍高速です。作成した可変コピーを返すことに問題がない場合は、Fisher-Yatesの方が10要素の方が高速です。
私は、小さいサイズと大きいサイズの両方で高速な優れたシャッフルアルゴを使用します。
これがプログラムです-あなたはInstrumentsの使い方を知っています!
#import <Foundation/Foundation.h>
static NSArray * imp_RandomizeUsingSortedArrayUsingComparator(NSArray * arr) {
return [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return arc4random_uniform(3) - 1; // one of -1, 0, or 1
}];
}
__attribute__((__noinline__)) static void RandomizeUsingSortedArrayUsingComparator(NSArray * arr) {
@autoreleasepool { imp_RandomizeUsingSortedArrayUsingComparator(arr); }
}
static NSArray * imp_RandomizeUsingMutableCopy(NSArray * arr) {
if (1 >= arr.count) {
return [arr.copy autorelease];
}
NSMutableArray * cp = [arr.mutableCopy autorelease];
u_int32_t i = (u_int32_t)cp.count;
while (i > 1) {
--i;
const u_int32_t j = arc4random_uniform(i);
[cp exchangeObjectAtIndex:i withObjectAtIndex:j];
}
// you may not favor creating the concrete copy
return [cp.copy autorelease];
}
__attribute__((__noinline__)) static void RandomizeUsingMutableCopy(NSArray * arr) {
@autoreleasepool { imp_RandomizeUsingMutableCopy(arr); }
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSMutableArray * filled = [NSMutableArray array];
for (NSUInteger i = 0; i < 1000000; ++i) {
[filled addObject:@""];
}
NSArray * concrete = filled.copy;
for (NSUInteger i = 0; i < 100; ++i) {
RandomizeUsingSortedArrayUsingComparator(concrete);
RandomizeUsingMutableCopy(concrete);
}
[concrete release];
}
return 0;
}