Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to initialize NSMutableString object?

If I take a following question. What is the best way to initialize NSMutableString Class? (All instance will be return at unexpected times... so I'll assume that the initialization as follows:)

  1. If I know in advance the amount of work. ( expected )

    NSMutableString *str1 = [NSMutableString stringWithString:@""];
    NSMutableString *str2 = [NSMutableString stringWithCapacity:0];
    NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];
    NSMutableString *str4 = [NSMutableString string];
    
    for(int i = 0; i< 1000; i++)
    {
        //The following tasks.(Adding to the string to continue working.)
        [/*str1~str4*/ appendFormat:@"%d", i];
    }
    
  2. If I don't know in advance the amount of work. ( unexpected )

    NSMutableString *str1 = [NSMutableString stringWithString:@""];
    NSMutableString *str2 = [NSMutableString stringWithCapacity:0];
    NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];
    NSMutableString *str4 = [NSMutableString string];
    
    for(int i = 0; i< /*a large of size(unpredictable)*/ ; i++)
    {
        //The following tasks.(Adding to the string to continue working.)
        [/*str1~str4*/ appendFormat:@"%d", i];
    }
    

Largely split into two when performing these tasks, What is the best way to initialize?

I sometimes when working with these task is also confusing.

like image 660
bitmapdata.com Avatar asked Dec 26 '11 15:12

bitmapdata.com


People also ask

What is NSMutableString?

NSMutableString is the abstract base class for a cluster of classes representing strings whose contents can be changed. It inherits from NSString. It extends the interface it inherits from NSString by adding methods to change the string contents.

What is NSMutableString in Swift?

The NSMutableString class declares the programmatic interface to an object that manages a mutable string—that is, a string whose contents can be edited—that conceptually represents an array of Unicode characters.


2 Answers

Case 1

Of the options listed, I'd use:

NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];

…if you know the destination size, or estimate it with a little room at the top and are able to quickly determine the exact size, or the size worst case scenario, this could save multiple reallocate and copy operations. If you don't know the size in the worst case scenario, or if it takes a lot of time to calculate, then you may as well use [NSMutableString string] or [NSMutableString new]. Also, *WithCapacity is a hint, which the frameworks are free to ignore.

Of course, the body of your loop and the size you reserve also implies that all the values are [0…9] (specifically, that all values consume one character), and you could in that case likely do far better by using format strings with more arguments. However, i is obviously larger than 9 for most iterations, and will consume on average 3 characters each, so 3000 would be a more appropriate reserve capacity for the exact code you posted.

Case 2

Of the options listed, I'd use:

NSMutableString *str4 = [NSMutableString string];

Even better, if you don't need to add it to an autorelease pool: [NSMutableString new] or [[NSMutableString alloc] init].

Other Notes

Yes, keeping objects out of autorelease pools (e.g. use alloc+init) can improve performance and reduce peak memory usage significantly. Sometimes, this is beyond your control, and in some environments (e.g. ARC), this may happen even though you use an autoreleased convenience constructor - e.g. [NSMutableString string].

The Faster Solution

Finally, if this case you have outlined really is a performance concern, the fastest way would be to create a char buffer on the stack and then create one NSString from the result of copying the numbers over to the char buffer. Assuming your ints are all 0-9, it would be very fast and easy, then simply create an NSString from the (terminated) cstring. You can even do this if the input size varies, or is very large (results in a very long string).

like image 187
justin Avatar answered Sep 29 '22 11:09

justin


It doesn't really matter.

If you've optimized your program so far that this decision will have a measurable effect on its overall performance, pat yourself on the back or, as Sheldon from BBT would say, "have a chocolate!"

PS:
If you precisely know the size up front or have a really good estimate on it, then use that size in stringWithCapacity: or initWithCapacity: if you don't, then don't even bother — let the framework decide, it's pretty damn clever!

like image 30
danyowdee Avatar answered Sep 29 '22 12:09

danyowdee