Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

mikezang

macrumors 6502a
Original poster
May 22, 2010
861
9
Tokyo, Japan
I want to know which array has a better performance.

Method1, define a NSMutableArray, and append item to that array.

Method2, define a NSArrat, append item to a temporary NSMutableArray, copy Mutable array to Array, then release mutable array.
 

(marc)

macrumors 6502a
Sep 15, 2010
724
2
the woods
Method 1:
Code:
NSMutableArray *mutableItems = [[NSMutableArray alloc] initWithCapacity:1000];
for (int i = 0; i < 10000; i++) {
    [mutableItems addObject:[NSDate date]];
}
[mutableItems release];

Method 2:
Code:
NSArray *items = [[[NSArray alloc] init] autorelease];
or (int i = 0; i < 10000; i++) {
    items = [items arrayByAddingObject:[NSDate date]];
}


Output:
Code:
Method 1: 0.011135 seconds.
Method 2: 9.712520 seconds.


This is highly informal, though.
 

mikezang

macrumors 6502a
Original poster
May 22, 2010
861
9
Tokyo, Japan
Your Method2 is not good enough, here is mine, can you test time for me? I am not sure how to test it:(
Code:
NSMutableArray *items = [[NSArray alloc] init];
for (int i = 0; i < 10000; i++) {
    items = [items addObject:[NSDate date]];
}

NSArray *mutableItems = [array arrayWithArray:items];
[items release];

Then I want to know the performance when use Mutable or Immutable array after init, do you have any suggestion?
 

chown33

Moderator
Staff member
Aug 9, 2009
10,760
8,454
A sea of green
Your Method2 is not good enough, here is mine, can you test time for me? I am not sure how to test it:(
Code:
NSMutableArray *items = [[NSArray alloc] init];
for (int i = 0; i < 10000; i++) {
    [COLOR="Red"]items = [/COLOR][items addObject:[NSDate date]];
}

NSArray *mutableItems = [[COLOR="Red"]array[/COLOR] arrayWithArray:items];
[items release];
Your code is wrong. [NSArray alloc] returns an immutable array. And the red-hilited code is nonsense.

Explain exactly what problem you're trying to solve, that you need to copy an NSMutableArray.

Also explain why the -copy method won't solve this problem. If you're not familiar with -copy, you should look it up in the reference docs for NSArray, NSMutableArray, and the NSCopying protocol. You're the only one who can do this, because no one else knows what problem you're trying to solve.
 

mikezang

macrumors 6502a
Original poster
May 22, 2010
861
9
Tokyo, Japan
Your code is wrong. [NSArray alloc] returns an immutable array. And the red-hilited code is nonsense.

Explain exactly what problem you're trying to solve, that you need to copy an NSMutableArray.

Also explain why the -copy method won't solve this problem. If you're not familiar with -copy, you should look it up in the reference docs for NSArray, NSMutableArray, and the NSCopying protocol. You're the only one who can do this, because no one else knows what problem you're trying to solve.
It is said the mutable array is not better performance than immutable array, so that I want to use a immutable array, but immutable array cannot be added with items, so I use a temp mutable array to add items, then copy it to immutable array and use it for long time without modify.

Can you show me your good idea code if you have?
 

(marc)

macrumors 6502a
Sep 15, 2010
724
2
the woods
It is said the mutable array is not better performance than immutable array, so that I want to use a immutable array, but immutable array cannot be added with items, so I use a temp mutable array to add items, then copy it to immutable array and use it for long time without modify.

Can you show me your good idea code if you have?

Reread post #2. According to my informal testing, using the mutable array takes ~0.1% of the time it takes to use the immutable array solution I provided. Whoever says using Method 2 is faster than Method 1 is simply wrong. Unless your a CS expert (and you're not), you are not going to write anything better than Apple's NSMutableArray. If you fear that NSMutableArray for some reason causes overhead down the road when you no longer modify its contents, you can always switch to an immutable array:

Code:
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];

// fill the array here

NSArray *immutableArray = [[NSArray alloc] initWithArray:mutableArray];
[mutableArray release];
 

mikezang

macrumors 6502a
Original poster
May 22, 2010
861
9
Tokyo, Japan
If you fear that NSMutableArray for some reason causes overhead down the road when you no longer modify its contents, you can always switch to an immutable array:

Code:
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];

// fill the array here

NSArray *immutableArray = [[NSArray alloc] initWithArray:mutableArray];
[mutableArray release];
This is what I want to know, is this method better performance than your method1 when use it it, not only fill it, because last code in above code take a few time than your method1, but if it has a very good performance than your method1 when refer it a lot of times, I this above code is better, may I make sense?
 

(marc)

macrumors 6502a
Sep 15, 2010
724
2
the woods
This is what I want to know, is this method better performance than your method1 when use it it, not only fill it, because last code in above code take a few time than your method1, but if it has a very good performance than your method1 when refer it a lot of times, I this above code is better, may I make sense?

Well, you're only going to create the immutable array from the mutable one once – as long as you're not using HUGE arrays, it shouldn't take long compared to filling up the array in first place.

But only testing in your particular situation can reveal what's best. Just implement your various ideas, test them and see what turns out to be the best.

On a side note: You seem to be very concerned about optimization. Make sure you read this Wikipedia article, and remember that "premature optimization is the root of all evil".
 

mikezang

macrumors 6502a
Original poster
May 22, 2010
861
9
Tokyo, Japan
Well, you're only going to create the immutable array from the mutable one once – as long as you're not using HUGE arrays, it shouldn't take long compared to filling up the array in first place.

But only testing in your particular situation can reveal what's best. Just implement your various ideas, test them and see what turns out to be the best.
Well, I will follow it.
On a side note: You seem to be very concerned about optimization. Make sure you read this Wikipedia article, and remember that "premature optimization is the root of all evil".
You are right, like you said, I am afraid of about performance, I am not sure why, maybe is due to my Personality, though I see it is better to optimize after I created my app and it has very bad performance:(
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
Mike, you haven't communicated your goal. What do you mean by performance? Creation of the array or reading from the array? The code in this thread has focused on creation but I think you may mean reading from the array.

You can use code like this to time your process

Code:
NSTimeInterval	start = [NSDate timeIntervalSinceReferenceDate];

// process here

NSTimeInterval	end = [NSDate timeIntervalSinceReferenceDate];

NSLog(@"elapsed time = %g", (end - start) * 1000.0);

Also you need to make certain that the compiler doesn't optimize away parts of your code because it doesn't appear to be doing anything useful. It may be best to put your code into a function and return a value from the function.

While I generally agree that spending a lot of time optimizing code that hasn't been proven to be slow or a bottleneck in your app can be a waste of time I think in this case that doesn't necessarily apply. The difference between the naive code and the optimized code might only be one line. Just don't spend a week working out the result.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,760
8,454
A sea of green
Well, you're only going to create the immutable array from the mutable one once – as long as you're not using HUGE arrays, it shouldn't take long compared to filling up the array in first place.

If the array is large enough, it could run out of memory, even though this might be a temporary condition.
 

(marc)

macrumors 6502a
Sep 15, 2010
724
2
the woods
Well, I will follow it.

You are right, like you said, I am afraid of about performance, I am not sure why, maybe is due to my Personality, though I see it is better to optimize after I created my app and it has very bad performance:(

Could you elaborate on what you're trying to do? If your app performs badly, you might need to rethink your approach on tackling the problem you're dealing with - fine-grained optimization as discussed in this thread will most likely not yield the major performance-gains you'll want.

The time needed to perform a search on an array grows as the array grows. This means that maybe you should reconsider if you really need all that data in your array (the tight memory constraints on 1st gen hardware come into play, as well).
Or you could use Core Data or even SQLite directly.

If you give us some more information about what you're trying to do, we'll be able to give better advice :)


EDIT: For the interested reader: Alternative Objective-C object allocation for large arrays
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.