最近需要将c++代码改到objective c下,c++代码中有用到std::list容器。查询后得知NSSet与NSArray都比较符合标准。到底用哪个呢。
下面是网上搜到的普遍答案
NSSet和我们常用NSArry区别是:在搜索一个一个元素时NSSet比NSArray效率高,主要是它用到了一个算法hash(散列,也可直译为哈希);开发文档中这样解释:You can use sets as an alternative to arrays when the order of elements isn’t important and performance in testing whether an object is contained in the set is a consideration—while arrays are ordered, testing for membership is slower than with sets.
比如你要存储元素A,一个hash算法直接就能直接找到A应该存储的位置;同样,当你要访问A时,一个hash过程就能找到A存储的位置。而对于NSArray,若想知道A到底在不在数组中,则需要便利整个数组,显然效率较低了;
但是我笨啊。只理解如果搜索一个值,NSSet是速度最快的,那其他情况呢。所以做了个实验
// // main.m // test // // Created by yanzhao on 13-12-9. // Copyright (c) 2013年 yanzhao. All rights reserved. // #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { NSInteger iterationIndex; NSAutoreleasePool *innerPool; const NSInteger NUM_ELEMENTS = 1000000; const NSInteger NUM_TEST_ITERATIONS = 3; NSDate *startTime; NSDate *endTime; NSMutableArray *objects = [NSMutableArray arrayWithCapacity:NUM_ELEMENTS]; NSLog(@"Constructing test data for %d elements.", NUM_ELEMENTS); // // Preconstruct the arrays of objects to use in the tests // NSAutoreleasePool *constructionPool = [[NSAutoreleasePool alloc] init]; for (iterationIndex = 0; iterationIndex < NUM_ELEMENTS; iterationIndex++) { NSNumber *objectValue = [NSNumber numberWithInteger:iterationIndex]; [objects addObject:objectValue]; } [constructionPool drain]; for (int i = 0; i < NUM_TEST_ITERATIONS; i++) { NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init]; NSLog(@"=== Beginning test loop. Iteration %d of %d ===", i + 1, NUM_TEST_ITERATIONS); NSMutableArray *arrayOfObjects = [NSMutableArray arrayWithCapacity:NUM_ELEMENTS]; NSMutableArray *unsizedArray = [NSMutableArray array]; NSMutableSet *setOfObjects = [NSMutableSet setWithCapacity:NUM_ELEMENTS]; NSMutableSet *setFromArray = nil; NSMutableSet *unsizedSet = [NSMutableSet set]; // // Test 1: Array construction when arrayWithCapacity: is used // innerPool = [[NSAutoreleasePool alloc] init]; startTime = [NSDate date]; for (NSNumber *number in objects) { [arrayOfObjects addObject:number]; } endTime = [NSDate date]; NSLog(@"Constructing the preallocated array took %g seconds", [endTime timeIntervalSinceDate:startTime]); [innerPool drain]; // // Test 2: Array construction when arrayWithCapacity: is NOT used // innerPool = [[NSAutoreleasePool alloc] init]; startTime = [NSDate date]; for (NSNumber *number in objects) { [unsizedArray addObject:number]; } endTime = [NSDate date]; NSLog(@"Constructing the unpreallocated array took %g seconds", [endTime timeIntervalSinceDate:startTime]); [innerPool drain]; // // Test 2: Array construction when arrayWithCapacity: is NOT used // innerPool = [[NSAutoreleasePool alloc] init]; startTime = [NSDate date]; for (NSNumber *number in arrayOfObjects) { } endTime = [NSDate date]; NSLog(@"Iterating the array took %g seconds", [endTime timeIntervalSinceDate:startTime]); [innerPool drain]; // // // // Test 2a: Array querying by isEqualTo: // // // innerPool = [[NSAutoreleasePool alloc] init]; // startTime = [NSDate date]; // for (NSNumber *number in objects) // { // [arrayOfObjects indexOfObject:number]; // } // endTime = [NSDate date]; // NSLog(@"Array querying by isEqualTo: took %g seconds", // [endTime timeIntervalSinceDate:startTime]); // [innerPool drain]; // // // // // Test 2b: Array querying by pointer value // // // innerPool = [[NSAutoreleasePool alloc] init]; // startTime = [NSDate date]; // for (NSNumber *number in objects) // { // [arrayOfObjects indexOfObjectIdenticalTo:number]; // } // endTime = [NSDate date]; // NSLog(@"Array querying by pointer value took %g seconds", // [endTime timeIntervalSinceDate:startTime]); // [innerPool drain]; // // Test 3: Set construction when setWithCapacity: is used // innerPool = [[NSAutoreleasePool alloc] init]; startTime = [NSDate date]; for (NSNumber *number in objects) { [setOfObjects addObject:number]; } endTime = [NSDate date]; NSLog(@"Constructing the preallocated set took %g seconds", [endTime timeIntervalSinceDate:startTime]); [innerPool drain]; // // Test 4: Set construction when setWithCapacity: is NOT used // innerPool = [[NSAutoreleasePool alloc] init]; startTime = [NSDate date]; for (NSNumber *number in objects) { [unsizedSet addObject:number]; } endTime = [NSDate date]; NSLog(@"Constructing the unpreallocated set took %g seconds", [endTime timeIntervalSinceDate:startTime]); [innerPool drain]; // // Test 4z: Set construction directly from an array of objects // innerPool = [[NSAutoreleasePool alloc] init]; startTime = [NSDate date]; setFromArray = [NSSet setWithArray:objects]; endTime = [NSDate date]; NSLog(@"Constructing the set from an array took %g seconds", [endTime timeIntervalSinceDate:startTime]); [innerPool drain]; // // Test 4y: Set iterating // innerPool = [[NSAutoreleasePool alloc] init]; startTime = [NSDate date]; for (NSNumber *number in setOfObjects) { } endTime = [NSDate date]; NSLog(@"Iterating the set took %g seconds", [endTime timeIntervalSinceDate:startTime]); [innerPool drain]; // // Test 4a: Set querying // innerPool = [[NSAutoreleasePool alloc] init]; startTime = [NSDate date]; for (NSNumber *number in objects) { [setOfObjects containsObject:number]; } endTime = [NSDate date]; NSLog(@"Set querying took %g seconds", [endTime timeIntervalSinceDate:startTime]); [innerPool drain]; [loopPool drain]; } } return 0; }执行后的结果
2013-12-09 23:13:13.438 test[425:303] Constructing test data for 1000000 elements. 2013-12-09 23:13:13.511 test[425:303] === Beginning test loop. Iteration 1 of 3 === 2013-12-09 23:13:13.547 test[425:303] Constructing the preallocated array took 0.029372 seconds 2013-12-09 23:13:13.604 test[425:303] Constructing the unpreallocated array took 0.055353 seconds 2013-12-09 23:13:13.610 test[425:303] Iterating the array took 0.00526196 seconds 2013-12-09 23:13:13.807 test[425:303] Constructing the preallocated set took 0.196128 seconds 2013-12-09 23:13:14.369 test[425:303] Constructing the unpreallocated set took 0.560845 seconds 2013-12-09 23:13:14.561 test[425:303] Constructing the set from an array took 0.189504 seconds 2013-12-09 23:13:14.594 test[425:303] Iterating the set took 0.013954 seconds 2013-12-09 23:13:14.761 test[425:303] Set querying took 0.166328 seconds 2013-12-09 23:13:14.822 test[425:303] === Beginning test loop. Iteration 2 of 3 === 2013-12-09 23:13:14.872 test[425:303] Constructing the preallocated array took 0.044945 seconds 2013-12-09 23:13:14.920 test[425:303] Constructing the unpreallocated array took 0.043245 seconds 2013-12-09 23:13:14.926 test[425:303] Iterating the array took 0.00522602 seconds 2013-12-09 23:13:15.137 test[425:303] Constructing the preallocated set took 0.20949 seconds 2013-12-09 23:13:15.638 test[425:303] Constructing the unpreallocated set took 0.500495 seconds 2013-12-09 23:13:15.806 test[425:303] Constructing the set from an array took 0.166952 seconds 2013-12-09 23:13:15.842 test[425:303] Iterating the set took 0.013066 seconds 2013-12-09 23:13:16.000 test[425:303] Set querying took 0.15639 seconds 2013-12-09 23:13:16.053 test[425:303] === Beginning test loop. Iteration 3 of 3 === 2013-12-09 23:13:16.091 test[425:303] Constructing the preallocated array took 0.032836 seconds 2013-12-09 23:13:16.137 test[425:303] Constructing the unpreallocated array took 0.044544 seconds 2013-12-09 23:13:16.143 test[425:303] Iterating the array took 0.00509703 seconds 2013-12-09 23:13:16.339 test[425:303] Constructing the preallocated set took 0.195937 seconds 2013-12-09 23:13:16.841 test[425:303] Constructing the unpreallocated set took 0.501613 seconds 2013-12-09 23:13:17.006 test[425:303] Constructing the set from an array took 0.164313 seconds 2013-12-09 23:13:17.043 test[425:303] Iterating the set took 0.012957 seconds 2013-12-09 23:13:17.200 test[425:303] Set querying took 0.156024 seconds Program ended with exit code: 0
如果实在是必须用NSSet,并且知道数据对象是唯一的,建议先构建NSArray,然后用setWithArray:构建NSSet