iOS基礎集合類NSArray和NSDictionary的性能,排序,枚舉

NSArray

排序

  • 逆序,array.reverseObjectEnumerator.allObjects
  • 數組中是字符串對象排序首選sortedArrayUsingSelector:
NSArray *array = @[@"John Appleseed", @"Tim Cook", @"Hair Force One", @"Michael Jurewitz"];
NSArray *sortedArray = [array sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
  • 存儲內容是數字
NSArray *numbers = @[@9, @5, @11, @3, @1];
NSArray *sortedNumbers = [numbers sortedArrayUsingSelector:@selector(compare:)];
  • 使用函數指針sortedArrayHint排序
- (NSData *)sortedArrayHint;
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator
     context:(void *)context;
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator
     context:(void *)context hint:(NSData *)hint;
  • 基于block的排序方法
- (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr;
- (NSArray *)sortedArrayWithOptions:(NSSortOptions)opts
     usingComparator:(NSComparator)cmptr;
  • 性能比較selector最快
Sorting 1000000 elements. selector: 4947.90[ms] function: 5618.93[ms] block: 5082.98[ms].
  • 更快的二分查找
typedef NS_OPTIONS(NSUInteger, NSBinarySearchingOptions) {
     NSBinarySearchingFirstEqual = (1UL << 8),
     NSBinarySearchingLastEqual = (1UL << 9),
     NSBinarySearchingInsertionIndex = (1UL << 10),
};

- (NSUInteger)indexOfObject:(id)obj
     inSortedRange:(NSRange)r
     options:(NSBinarySearchingOptions)opts
     usingComparator:(NSComparator)cmp;

//Time to search for 1000 entries within 1000000 objects. Linear: 54130.38[ms]. Binary: 7.62[ms]

枚舉

  • 使用indexesOfObjectsWithOptions:passingTest:
NSIndexSet *indexes = [randomArray indexesOfObjectsWithOptions:NSEnumerationConcurrent
     passingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
     return testObj(obj);
}];
NSArray *filteredArray = [randomArray objectsAtIndexes:indexes];
  • 傳統的枚舉
NSMutableArray *mutableArray = [NSMutableArray array];
for (id obj in randomArray) {
     if (testObj(obj)) {
          [mutableArray addObject:obj];
     }
}
  • block方式枚舉
NSMutableArray *mutableArray = [NSMutableArray array];
[randomArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
     if (testObj(obj)) {
          [mutableArray addObject:obj];
     }
}];
  • 通過下標objectAtIndex:
NSMutableArray *mutableArray = [NSMutableArray array];
for (NSUInteger idx = 0; idx < randomArray.count; idx++) {
     id obj = randomArray[idx];
     if (testObj(obj)) {
          [mutableArray addObject:obj];
     }
}
  • 使用比較傳統的學院派NSEnumerator
NSMutableArray *mutableArray = [NSMutableArray array];
NSEnumerator *enumerator = [randomArray objectEnumerator];
id obj = nil;
while ((obj = [enumerator nextObject]) != nil) {
     if (testObj(obj)) {
          [mutableArray addObject:obj];
     }
}
  • 使用predicate
NSArray *filteredArray2 = [randomArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id obj, NSDictionary *bindings) {
     return testObj(obj);
}]];
  • 各個方法枚舉時間參考,indexesOfObjectsWithOptions在開啟了并發枚舉的情況下比NSFastEnumeration快一倍。
枚舉方法 / 時間 [ms] 10.000.000 elements 10.000 elements
indexesOfObjects:, concurrent 1844.73 2.25
NSFastEnumeration (for in) 3223.45 3.21
indexesOfObjects: 4221.23 3.36
enumerateObjectsUsingBlock: 5459.43 5.43
objectAtIndex: 5282.67 5.53
NSEnumerator 5566.92 5.75
filteredArrayUsingPredicate: 6466.95 6.31

NSDictionary

性能

同樣數目的值,NSDictionary比NSArray要花費多得多的內存空間

排序

使用NSArray的排序方法將鍵數組排序為新的對象

- (NSArray *)keysSortedByValueUsingSelector:(SEL)comparator;
- (NSArray *)keysSortedByValueUsingComparator:(NSComparator)cmptr;
- (NSArray *)keysSortedByValueWithOptions:(NSSortOptions)opts
     usingComparator:(NSComparator)cmptr;

枚舉

  • keysOfEntriesWithOptions:passingTest:,可并行
NSSet *matchingKeys = [randomDict keysOfEntriesWithOptions:NSEnumerationConcurrent
passingTest:^BOOL(id key, id obj, BOOL *stop)
{
     return testObj(obj);
}];
NSArray *keys = matchingKeys.allObjects;
NSArray *values = [randomDict objectsForKeys:keys notFoundMarker:NSNull.null];
__unused NSDictionary *filteredDictionary = [NSDictionary dictionaryWithObjects:values
     forKeys:keys];
  • getObjects:andKeys: 枚舉,基于c數組
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
id __unsafe_unretained objects[numberOfEntries];
id __unsafe_unretained keys[numberOfEntries];
[randomDict getObjects:objects andKeys:keys];
for (int i = 0; i < numberOfEntries; i++) {
     id obj = objects[i];
     id key = keys[i];
     if (testObj(obj)) {
          mutableDictionary[key] = obj;
     }
}
  • block枚舉
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
[randomDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
     if (testObj(obj)) {
          mutableDictionary[key] = obj;
     }
}];
  • NSFastEnumeration
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
for (id key in randomDict) {
     id obj = randomDict[key];
     if (testObj(obj)) {
          mutableDictionary[key] = obj;
     }
}
  • NSEnumeration
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
NSEnumerator *enumerator = [randomDict keyEnumerator];
id key = nil;
while ((key = [enumerator nextObject]) != nil) {
     id obj = randomDict[key];
     if (testObj(obj)) {
          mutableDictionary[key] = obj;
     }
}
  • 各個方法枚舉時間參考
枚舉方法 / 時間 [ms] 50.000 elements 1.000.000 elements
keysOfEntriesWithOptions:, concurrent 16.65 425.24
getObjects:andKeys: 30.33 798.49
keysOfEntriesWithOptions: 30.59 856.93
enumerateKeysAndObjectsUsingBlock: 36.33 882.93
NSFastEnumeration 41.20 1043.42
NSEnumeration 42.21 1113.08
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 卷首語 歡迎來到 objc.io 第七期! 這個月,我們選擇了 Foundation 框架作為我們的主題。 Fou...
    評評分分閱讀 1,562評論 0 8
  • 尊重知識,轉發請注明出處:iOS開發遍歷集合方法總結 想到循環遍歷數組、字典這些常見的集合,大家腦子里第一反應就是...
    張云龍閱讀 24,714評論 17 66
  • 數組可對其中包含的元素進行排序。 在排序前,我們需要定義一個Model類,將Model類對象添加至數組中。 定義一...
    SkyMing一C閱讀 10,975評論 0 15
  • 站在前輩的肩膀上前行 UIKit框架和Foundation框架 所有的Mac OS X和IOS程序都是由大量的對象...
    zysmoon閱讀 8,749評論 0 16
  • 是一輪噴薄欲出的太陽, 滿身都是向上的力量。 那烏云擋不了你的笑臉, 雨后的彩虹更加燦爛輝煌。 是一棵破土而出的幼...
    欣榮Y閱讀 483評論 13 36