初始化 NSMutableString 对象的最佳方法是什么?

发布于 2024-12-23 06:46:09 字数 991 浏览 3 评论 0原文

如果我提出以下问题。初始化 NSMutableString 类的最佳方法是什么? (所有实例都会在意外的时间返回......所以我假设初始化如下:)

  1. 如果我提前知道工作量。 (预计)

    NSMutableString *str1 = [NSMutableString stringWithString:@""];
    NSMutableString *str2 = [NSMutableString stringWithCapacity:0];
    NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];
    NSMutableString *str4 = [NSMutableString 字符串];
    
    for(int i = 0; i< 1000; i++)
    {
        //以下任务。(添加到字符串中以继续工作。)
        [/*str1~str4*/appendFormat:@"%d", i];
    }
    
  2. 如果我事先不知道工作量。 (出乎意料)

    NSMutableString *str1 = [NSMutableString stringWithString:@""];
    NSMutableString *str2 = [NSMutableString stringWithCapacity:0];
    NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];
    NSMutableString *str4 = [NSMutableString 字符串];
    
    for(int i = 0; i< /*很大的尺寸(不可预测)*/ ; i++)
    {
        //以下任务。(添加到字符串中以继续工作。)
        [/*str1~str4*/appendFormat:@"%d", i];
    }
    

在执行这些任务时很大程度上分为两部分,初始化的最佳方式是什么?

有时我在处理这些任务时也会感到困惑。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

中性美 2024-12-30 06:46:09

案例 1

在列出的选项中,我会使用:

NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];

……如果您知道目标尺寸,或者用顶部的一点空间来估计它,并且能够快速确定确切的尺寸,或者尺寸最坏的情况下,这可以节省多次重新分配和复制操作。如果你不知道最坏情况下的大小,或者需要花费大量时间来计算,那么你不妨使用 [NSMutableString string][NSMutableString new]。另外,*WithCapacity 是一个提示,框架可以忽略它。

当然,循环体和保留的大小也意味着所有值都是 [0…9](具体来说,所有值都消耗一个字符),在这种情况下,您可以通过使用格式字符串做得更好有更多的论点。但是,对于大多数迭代来说,i 显然大于 9,并且每次平均会消耗 3 个字符,因此对于您发布的确切代码来说,3000 是更合适的保留容量。

情况 2

在列出的选项中,我会使用:

NSMutableString *str4 = [NSMutableString string];

如果您不需要将其添加到自动释放池,那就更好了: [NSMutableString new][[NSMutableString alloc] init]

其他说明

是的,将对象保留在自动释放池之外(例如使用alloc+init)可以提高性能并显着减少内存使用峰值。有时,这超出了您的控制范围,并且在某些环境(例如 ARC)中,即使您使用自动释放的便利构造函数,也可能会发生这种情况 - 例如 [NSMutableString string]

更快的解决方案

最后,如果您概述的这种情况确实是性能问题,那么最快的方法是在堆栈上创建一个 char 缓冲区,然后创建一个 NSString 来自将数字复制到 char 缓冲区的结果。假设您的 int 都是 0-9,这将非常快速且简单,然后只需从(终止的)cstring 创建一个 NSString 即可。如果输入大小变化或非常大(导致非常长的字符串),您甚至可以执行此操作。

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).

二智少女猫性小仙女 2024-12-30 06:46:09

这并不重要。

如果到目前为止您已经优化了您的程序,并且这一决定将对其整体性能产生可衡量的影响,那么请拍拍自己的背,或者像 BBT 的 Sheldon 所说的那样,“吃块巧克力吧!”

PS:
如果您预先准确地知道大小或对其有很好的估计,则可以在 stringWithCapacity:initWithCapacity: 中使用该大小(如果您不知道,则不要这样做)甚至不必费心——让框架来决定,它非常聪明

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!

一张白纸 2024-12-30 06:46:09

这是最短的方法:

NSMutableString *string = [@"" mutableCopy];

Here is the shortest way:

NSMutableString *string = [@"" mutableCopy];
深爱成瘾 2024-12-30 06:46:09
NSMutableString *str1 = [NSMutableString stringWithString:@""];

不好,毫无意义地创建一个 NSString (@""),然后复制到一个新的 NSMutable String

NSMutableString *str2 = [NSMutableString stringWithCapacity:0];

不好,容量为 0 的 NSMutableString 在第一次添加时需要膨胀。

NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];

很好,如果 1000 有一定的意义(即它是您正在处理的内容的预期大小)。

NSMutableString *str4 = [NSMutableString string];

很好,使用一种方便的方法,就像执行 [NSMutableString alloc] init];

NSMutableString *str1 = [NSMutableString stringWithString:@""];

Bad, a NSString (@"") is pointlessly created, then copied into a new NSMutable String

NSMutableString *str2 = [NSMutableString stringWithCapacity:0];

Bad, a NSMutableString with 0 capacity will need to be inflated upon the first addition to it.

NSMutableString *str3 = [NSMutableString stringWithCapacity:1000];

Good, if 1000 has some significance (i.e. it's an expected size for the content you're working with).

NSMutableString *str4 = [NSMutableString string];

Good, using a convenience method, which is is like doing [NSMutableString alloc] init];

优雅的叶子 2024-12-30 06:46:09

如果您预先知道大小,请使用

 [NSMutableString stringWithCapacity: _Known_Size_];

如果您预先不知道大小,请使用

 [NSMutableString stringWithCapacity: _small_number_];

那么可变字符串将根据需要增长。

If you know the size upfront, use

 [NSMutableString stringWithCapacity: _Known_Size_];

If you don't know the size up front, use

 [NSMutableString stringWithCapacity: _small_number_];

Then the mutable string will grow as it needs to.

诗化ㄋ丶相逢 2024-12-30 06:46:09

在 Swift 5 中:

var mutableString = NSMutableString("")

In Swift 5:

var mutableString = NSMutableString("")
悲凉≈ 2024-12-30 06:46:09

分配和初始化对象总是更好,而不是使用类方法来创建它(这会将其放入最近的自动释放池中)。

因此,

NSMutableString* stringOne = [[NSMutableString alloc] initWithCapacity:capacity];

不要

NSMutableString* stringTwo = [NSMutableString stringWithCapacity:capacity];

记住,当你使用完 stringOne 时,必须释放它,而不是 stringTwo,因为 stringWithCapacity: 类方法返回一个自动释放的对象。

在此处阅读有关该主题的更多信息:http://www.mulle-kybernetik。 com/artikel/Optimization/opti-5.html

It is always better to allocate and initialize an object, not use a class method to create it (which puts it in the closest autorelease pool).

So,

NSMutableString* stringOne = [[NSMutableString alloc] initWithCapacity:capacity];

instead of

NSMutableString* stringTwo = [NSMutableString stringWithCapacity:capacity];

Just remember that you have to release stringOne when you are done with it, but not stringTwo, because the stringWithCapacity: class method returns an autoreleased object.

Read more about the topic here: http://www.mulle-kybernetik.com/artikel/Optimization/opti-5.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文