2013-02-13 5 views
18

最近、私は配列に関して多くの作業をしています。[NSArray arrayWithArray:]と[NSArray copy]の相違点

NSArray *array = [NSArray arrayWithArray:someArray]; 

NSArray *array = [someArray copy]; 

それが高速であるのはどれですか? NSMutableArraymutableCopyの場合はどうなりますか?

答えて

23

どちらが速いのですか?

心配しないでください。時期尚早の最適化。

主な違い:最初のアプローチでは、2番目の行に作成されたオブジェクトを所有している間に、所有していないautoreleased "コピー"がリリースされる必要はありません。 両方の配列は、そのままでは不変です。

+0

ARCはどうですか? –

+0

私はARCで2番目のものを使うと言うので、オートリリースされていないので、オートリリースプールがフラッシュされるまで保持されません。しかし、同じrunloop内(または@ autoreleasepool内)にたくさんの配列を作成しない限り、それは早すぎる最適化です。 –

1

おそらくそのうちの1つが高速です。百万回それらを実行し、誰かが勝つかどうかを確認します。

NSArrayNSMutableArrayの場合、変更可能なので、コピーされる不変の配列は実際にコピーを返す必要はありません。ただし、配列を変更できる場合は、元の配列を変更できるのでコピーする必要があります。もちろん、可変コピーを実行すると常に新しいオブジェクトを返す必要があります。

あなたのアプリケーション全体では、スピードとメモリの違いは、おそらくそれが起こっているすべてのものと比較して問題にはならないでしょう。

7

2つの違いは、後者が保持されることです。前者はオートリリースされます。

どちらのバージョンでも、アレイのシャローコピーが作成されます。あなたはNSMutableArrayNSArrayを代入しようとするよう

NSMutableArray *notMutableReally = [NSArray arrayWithArray:aMutableArray]; 

はあなたのコンパイラの警告を与える必要があります。

使用。

NSMutableArray *mutableArrayCopy = [NSMutableArray arrayWithArray:aMutableArray]; 

どちらが速いのですか?心配しないでください、彼らはあなたがやっているものの残りの部分よりもはるかに高速です。あなたが本当に気にしているのであれば、インストゥルメンツにチェック

4

主な違いは、(まあ、実際には具体的なクラスを使用-copy+arrayWithArray:NSArrayの新しいインスタンスを作成します。一方、(より効率的にそれを行うと、多分にNSArrayのより多くの適応サブクラスを使用することができます)自分自身をコピーする方法を良く知っているということですFoundationのby配列)、初期オブジェクトからのオブジェクトの同じリストを与えてください。また、それは余分なオートリリースを追加します。

だから-copyは非常に効率的です。

実際には不変のNSArraysの場合、-copy-retainを実行しているだけなので、新しいインスタンスを作成する必要はありません。他の回答に加えて

+0

これは正確ではありません。コピーを作成すると、新しい配列が作成されます。 – thierryb

+1

簡単なテストツールで試してみることができます(ここで私が正しいと信じる他の非常に良い理由はありません) – Julien

+0

@JulienあなたはFoundationクラスに精通しているようですが、NSArray 、NSDictionaryなどは変更可能ですか?すでに他の場所で議論が行われていますが、良い答えは見つかりませんでしたか? (-isKindOfClass:信頼できないと言われています。-respondsToSelector:@selector(addObject :)?)正しい方法を探しています...ありがとう! –

21

someArrayがnil、 である場合、最初の行は、空の配列にarrayポイントを作るし、第二は、nilに それポイントを作ることに注意します。これは、特に可変配列の重要な違いです。

3
NSMutableArray *arr = [NSMutableArray array]; 
for (int i = 0; i < 10000; i ++) 
{ 
    [arr addObject:@(i*1000000ULL)]; 
} 
// MARK 
// arr = (id)[NSArray arrayWithArray:arr]; 

NSTimeInterval t = [NSDate timeIntervalSinceReferenceDate]; 
NSArray *res = nil; 
for (int i = 0; i < 10000; i ++) 
{ 
    res = [arr copy]; 
} 
NSLog(@"time A: %f", [NSDate timeIntervalSinceReferenceDate] - t); 
t = [NSDate timeIntervalSinceReferenceDate]; 
for (int i = 0; i < 10000; i ++) 
{ 
    res = [NSArray arrayWithArray:arr]; 
} 
NSLog(@"time B: %f", [NSDate timeIntervalSinceReferenceDate] - t); 

時間A:1.572795、時間B:1.539150、B [NSArrayのarrayWithArray:]いつもより速いが、時間差は非常に小さいです。私たちは「MARK」をコメント解除し、代わりにNSArrayからNSMutableArrayのをコピーします、我々は他のランタイムのA持つかどうは、しかし:0.000473時間B:1.548400結果:スウィフトで〜3200倍高速

1

を、それは非常に異なるのです。 Swiftの新しいオープンソース基金のおかげで、init(array:)は与えられたアイテム(もしあれば)を使って新しい配列を作成しますが、は単にselfを返します。

public override func copy() -> AnyObject { 
     return copyWithZone(nil) 
    } 

    public func copyWithZone(zone: NSZone) -> AnyObject { 
     return self 
    } 

https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSArray.swift#L82

public convenience init(array: [AnyObject]) { 
     self.init(array: array, copyItems: false) 
    } 

    public convenience init(array: [AnyObject], copyItems: Bool) { 
     let optionalArray : [AnyObject?] = 
      copyItems ? 
       array.map { return Optional<AnyObject>(($0 as! NSObject).copy()) } : 
       array.map { return Optional<AnyObject>($0) } 

     // This would have been nice, but "initializer delegation cannot be nested in another expression" 
//  optionalArray.withUnsafeBufferPointer { ptr in 
//   self.init(objects: ptr.baseAddress, count: array.count) 
//  } 
     let cnt = array.count 
     let buffer = UnsafeMutablePointer<AnyObject?>.alloc(cnt) 
     buffer.initializeFrom(optionalArray) 
     self.init(objects: buffer, count: cnt) 
     buffer.destroy(cnt) 
     buffer.dealloc(cnt) 
    } 

https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSArray.swift#L116

ので、当然、copy()が速くなり、そして今、あなたは彼らの両方がどのように動作するかを知っています! (スイフトのみ)

+1

スウィフトでのこのような仕組みが分かりました:) –