最近需要将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
通过上面结果判断得出: 用NSArray。即使需要查找功能,如果数据量不大,不是太频繁,也不要用NSSet
如果实在是必须用NSSet,并且知道数据对象是唯一的,建议先构建NSArray,然后用setWithArray:构建NSSet