Ios 制作不可变对象的可变副本的首选方法?

Ios 制作不可变对象的可变副本的首选方法?,ios,foundation,Ios,Foundation,有两种选择(可能更多)。以NSSet为例: NSMutableSet * mutableSet = [ NSMutableSet setWithSet:nonMutableSet ] ; 或 这两种实现之间有什么区别吗?一个“更有效”吗?(其他示例包括NSArray/NSMutableArray和NSDictionary/NSMutableDictionary基准测试乐趣!) -setWithSet枚举集合的每个值,然后将其添加到新集合中。从CFBasicHashAddValue的实现来看(同

有两种选择(可能更多)。以NSSet为例:

NSMutableSet * mutableSet = [ NSMutableSet setWithSet:nonMutableSet ] ;

这两种实现之间有什么区别吗?一个“更有效”吗?(其他示例包括NSArray/NSMutableArray和NSDictionary/NSMutableDictionary

基准测试乐趣!)

-setWithSet枚举集合的每个值,然后将其添加到新集合中。从CFBasicHashAddValue的实现来看(同样在中),它看起来像是在重新设置集合中的每个值

Running    Time Self    Symbol Name
1605.0ms   86.0%    0.0     +[NSSet setWithSet:]
1605.0ms   86.0%    2.0       -[NSSet initWithSet:copyItems:]
1232.0ms   66.0%    68.0        -[__NSPlaceholderSet initWithObjects:count:]
1080.0ms   57.8%    299.0         CFBasicHashAddValue
324.0ms    17.3%    28.0        -[NSSet getObjects:count:]
272.0ms    14.5%    75.0          __CFBasicHashFastEnumeration
这种重新灰化在CFSet级别是有意义的。cfset在callBacks参数中接受CFSetHashCallBack;因此,两个CFNumbers的cfset可以指定不同的哈希例程。基金会的NSSet在后台使用CFSet,并有一个调用
-[NSObject hash]
的CFSetHashCallBack函数。(尽管我认为苹果可以优化这种情况,避免在两个集合具有相同的哈希回调时再次出现这种情况)


请注意,此基准仅适用于NSSet(NSNumbers),其他集合类可能具有不同的性能特征。

好问题,我怀疑可能会有很多关于此的争论。如果您想帮大家一个忙,对它进行基准测试,然后自己回答这个问题:)不过我想应该不会有太大的区别。@fzwo我想我可以做到。。虽然这在一定程度上是一个编程哲学问题:)我相信阵列可以有不同的支持实现(在NSArray类集群的私有子类中),这取决于诸如项目数量之类的情况,这会进一步使基准测试复杂化(但通常会提高性能)。是的!此外,集合中对象的数量也会有所不同。作为一个注释,对于使用上述基准的数组,它看起来像-MutabelPopy/AutoRelaySoad稍微慢一些,这些事情经常被调整——这是一个很好的想法,经常比基准类的性能特征假设重做基准:
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{ @autoreleasepool {
    NSMutableSet *masterSet = [NSMutableSet set];

    for (NSInteger i = 0; i < 100000; i++) {
        [masterSet addObject:[NSNumber numberWithInteger:i]];
    }

    clock_t start = clock();

    for (NSInteger i = 0; i < 100; i++) {
        @autoreleasepool {
            [NSMutableSet setWithSet:masterSet];
        }
    }

    NSLog(@"a: --- %lu", clock() - start);

    sleep(1);

    start = clock();

    for (NSInteger i = 0; i < 100; i++) {
        @autoreleasepool {
            [[masterSet mutableCopy] autorelease]; 
        }
    }

    NSLog(@"b: --- %lu", clock() - start);

    return 0;
} }
Running  Time   Self  Symbol Name
256.0ms  61.5%  0.0   -[NSObject mutableCopy]
256.0ms  61.5%  0.0     -[__NSCFSet mutableCopyWithZone:]
256.0ms  61.5%  0.0       CFSetCreateMutableCopy
255.0ms  61.2%  156.0       CFBasicHashCreateCopy
97.0ms   23.3%  44.0          __CFSetStandardRetainValue
Running    Time Self    Symbol Name
1605.0ms   86.0%    0.0     +[NSSet setWithSet:]
1605.0ms   86.0%    2.0       -[NSSet initWithSet:copyItems:]
1232.0ms   66.0%    68.0        -[__NSPlaceholderSet initWithObjects:count:]
1080.0ms   57.8%    299.0         CFBasicHashAddValue
324.0ms    17.3%    28.0        -[NSSet getObjects:count:]
272.0ms    14.5%    75.0          __CFBasicHashFastEnumeration