在開發應用程序的時候,有時咱們須要對一組無序的內容進行排序,iOS中有系統自帶的方法來對NSAray進行排序,咱們來對這些方法進行性能上的對比:git
NSComparator排序github
NSDescriptor排序算法
function排序數組
quickSort排序dom
因爲排序的對象常常是自定義的,所以咱們定義一個以下的對象:函數
@interface Topic : NSObject @property (nonatomic, assign) NSInteger ID; @property (nonatomic, copy) NSString *content; @end
而後生成一個包含10000個對象的數組,對像的ID都是隨機的:性能
NSMutableArray *unSortedArray = [NSMutableArray new]; for(NSInteger i = 0; i <10000;i++) { Topic *topic = [Topic new]; topic.ID = arc4random() % 10000; topic.content = [NSString stringWithFormat:@"This is :%@",[NSNumber numberWithLong: topic.ID]]; [unSortedArray addObject:topic]; }
計算時間差的方法:優化
CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); CFAbsoluteTime end = CFAbsoluteTimeGetCurrent(); NSLog(@"time cost: %0.3f ms", (end - start)*1000);
使用NSComparator排序ui
comparator的定義以下所示:atom
typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
上面的參數(obj一、obj2)就是咱們將要作比較的對象。block返回的結果爲NSComparisonResult類型來表示兩個對象的順序。
對上述的無序array的對象ID進行排序,代碼以下:
NSArray *sortedArray = [unSortedArray sortedArrayUsingComparator:^(id obj1,id obj2)
{
NSInteger val1 = ((Topic*)obj1).ID;
NSInteger val2 = ((Topic*)obj2).ID;
//升序,假如須要降序的話,只須要修改下面的邏輯
if (val1 < val2)
{
return NSOrderedAscending;
}
else
{
return NSOrderedDescending;
}
}
使用NSDescriptor排序
sort descriptor能夠很方便的對數組進行多個key的排序。好比要對數組的對象先作ID排序,而後在對content進行排序的話,能夠寫成:
NSSortDescriptor *firstDescriptor = [[NSSortDescriptor alloc] initWithKey:@"ID" ascending:YES]; NSSortDescriptor *secondDescriptor = [[NSSortDescriptor alloc] initWithKey:@"content" ascending:YES]; NSArray *sortArray = [NSArray arrayWithObjects:firstDescriptor,secondDescriptor,nil]; NSArray *sortedArray = [unSortedArray sortedArrayUsingDescriptors:sortArray];
使用函數排序
具體代碼實現方式以下:
NSInteger customSort(id obj1, id obj2,void* context)
{
Topic *topic1 = (Topic*)obj1; Topic *topic2 = (Topic*)obj2; NSInteger val1 = topic1.ID; NSInteger val2 = topic2.ID; if (val1 > val2)
{ return (NSComparisonResult)NSOrderedDescending; } if (val1 < val2)
{ return (NSComparisonResult)NSOrderedAscending; } return (NSComparisonResult)NSOrderedSame; } sortedArray = [array sortedArrayUsingFunction:customSort context:nil];
快速排序
快速排序我想大多數的人都聽過,因爲排序效率在同爲O(N*logN)的幾種排序方法中效率較高,所以咱們也對比以一下快排的表現,下面是快排的代碼:
void quickSort(NSMutableArray *array, NSInteger first, NSInteger last, NSComparator comparator)
{ if (first >= last) return; id pivot = array[(first + last) / 2]; NSInteger left = first; NSInteger right = last; while (left <= right) { while (comparator(array[left], pivot) == NSOrderedAscending) left++; while (comparator(array[right], pivot) == NSOrderedDescending) right--; if (left <= right) [array exchangeObjectAtIndex:left++ withObjectAtIndex:right--]; } quickSort(array, first, right, comparator); quickSort(array, left, last, comparator); } NSArray* sort(NSArray *unsorted, NSComparator comparator) { NSMutableArray *a = [NSMutableArray arrayWithArray:unsorted]; quickSort(a, 0, a.count - 1, comparator);return a; } sortedArray = sort(array, ^(id obj1, id obj2) { Topic *topic1 = (Topic*)obj1; Topic *topic2 = (Topic*)obj2; NSNumber *val1 =[NSNumber numberWithLong:topic1.ID]; NSNumber *val2 = [NSNumber numberWithLong:topic2.ID]; return [val1 compare:val2]; });
結果對比:
iPhone4: 2014-10-17 13:51:31.980 Algorithm_test[9578:907] NSComparator sort time cost: 163.708ms 2014-10-17 13:51:32.273 Algorithm_test[9578:907] NSSortDescriptor sort time cost: 291.293ms 2014-10-17 13:51:32.559 Algorithm_test[9578:907] function sort time cost: 281.485ms 2014-10-17 13:51:36.582 Algorithm_test[9578:907] quick sort time cost: 4013.582ms
iPhone5s: 2014-10-17 14:02:59.323 Algorithm_test[2971:60b] NSComparator sort time cost: 19.238ms 2014-10-17 14:02:59.348 Algorithm_test[2971:60b] NSSortDescriptor sort time cost: 24.183ms 2014-10-17 14:02:59.380 Algorithm_test[2971:60b] function sort time cost: 31.967ms 2014-10-17 14:02:59.468 Algorithm_test[2971:60b] quick sort time cost: 86.205ms
能夠發現前3種系統自帶的方法運行速度很快,即使是在4這種老機器排序10000個對象也不到1s的時間,能夠看出蘋果對算法的優化仍是挺好的,可是快排的表現卻不盡如人意,至於5s機器上,上述的排序時間都在幾十毫秒,幾乎能夠忽略不計。所以建議在須要排序的時候採用系統自帶的方法,至於用哪一個能夠看狀況本身選擇。
示例代碼:https://github.com/FreeMind-LJ/HelloWrold/tree/master/Algorithm_test