这个问题已经解决了。http://en.wikipedia.org/wiki/Knuth_shuffle
templatetypedef 也对此发表了评论。
Fisher-Yates Shuffle amutableCopy
非常快,而且随机化效果更好。对于小型数组(10 个元素),您的建议比 Fisher-Yates shuffle 稍快,如下所示。对于大型数组(1000000 个元素),Fisher_Yates 比你的快 4 倍。如果您可以返回您制作的可变副本,那么对于 10 个元素,Fisher-Yates 也更快。
我会选择高级的随机播放算法,它对于小尺寸和大尺寸都很快。
这是程序——你知道如何使用仪器!
#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;
}