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:)
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];
}
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.
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.
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.
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 int
s 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).
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With