iOS開發之排序方法比較

在開發應用程序的時候,有時咱們須要對一組無序的內容進行排序,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

相關文章
相關標籤/搜索