【问题标题】:.ToString() creates a new string from StringBuilder, so why not use string directly?.ToString() 从 StringBuilder 创建一个新字符串,那么为什么不直接使用字符串呢?
【发布时间】:2016-02-07 10:43:53
【问题描述】:

我看到了与字符串生成器相关的问题,但无法找到相关答案。

我的问题是“在这里使用字符串生成器是否明智?如果不是,如何在这里明智地使用它”。

此方法将运行 100000 次。为了节省一些内存,我在这里使用了 stringbuilder。但问题是.ToString() 方法。无论如何,我必须使用.ToString() 方法创建一个字符串,所以为什么不将filename 初始化为字符串而不是StringBuilder

internal bool isFileExists()
{
    StringBuilder fileName = new StringBuilder(AppDomain.CurrentDomain.BaseDirectory + "Registry\\" + postalCode + ".html");
    if (System.IO.File.Exists(fileName.ToString()))
    {
        return true;
    }
    else
    {
        return false;
    }
}

所有库方法都使用字符串作为参数而不是字符串生成器,为什么? 我觉得我的概念很混乱。

【问题讨论】:

  • 在这种情况下使用 StringBuilder 似乎不会添加任何值,您通常会使用它将值附加到缓冲区,然后在完成后返回该字符串。你也可以在这里只使用一个string 而不是StringBuilder 实例。
  • 为什么不直接使用return System.IO.File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Registry\\" , postalCode , ".html"));
  • @Charlie 查看 SaverioTerracciano 的回答了解更多详情
  • 这里没有理由(真的没有理由)使用字符串生成器。它甚至不明智。

标签: c#


【解决方案1】:

您实际上是在此处创建 4 个strings。 第一个是AppDomain.CurrentDomain.BaseDirectory + "Registry\\"
第二个是当您将+ postalCode 添加到该字符串时。
添加+ ".html"时的第三个。
当您拨打fileName.ToString() 时,第四个。

如果你想使用StringBuilder,你应该这样做:

StringBuilder fileName = new StringBuilder(AppDomain.CurrentDomain.BaseDirectory);
fileName.Append("Registry\\");
fileName.Append(".html");

正如 Hans Kesting 善意地提醒我的那样,你并不是真的创造了 4 strings。编译器将其优化为对String.Concat() 的一次调用。

【讨论】:

  • 不完全是:string + string + string 被编译器翻译成对String.Concat 的单个调用
  • @HansKesting 是的,没错,我只是想展示没有编译器优化会发生什么
  • @HansKesting 感谢您的更正,但我认为编译器会进行某种优化,只是不知道具体是什么。
【解决方案2】:

在您的情况下,先创建 StringBuilder 然后创建 string 是没有意义的。

Strings 在 C# 中是不可变的,当您需要对它们进行更改(替换、追加等)时,会在字符串池中创建另一个字符串。 这样的分配是有成本的,如果有几个不同的操作,这个成本加起来就会变得非常昂贵。

StringBuilder 是一个可以内部更改的对象,并且对于上面的操作来说更快(成本更低),因此最好使用它。

其中一个比其他更好的点会根据场景而变化,但根据经验,如果您发现自己在相同的方法中一遍又一遍地更改相同的字符串,使用它可能是个好主意一个 StringBuilder 代替。

【讨论】:

    【解决方案3】:

    IO 操作(甚至File.Exists)比String 创建更耗时;你无法避免 File.Exists 测试,这就是为什么,恕我直言,可读性是最重要的:

    1. 字符串格式
    2. 没有冗余 if

    实施:

    internal bool isFileExists() {
      return File.Exists(String.Format("{0}Registry\\{1}.html", 
        AppDomain.CurrentDomain.BaseDirectory,
        postalCode));
    }
    

    【讨论】:

      【解决方案4】:

      看起来很奇怪 isFileExists() 不使用 postalCode 参数。它只是一个例子还是一段真实的代码?

      我建议你不要使用 File.Exists() 数千次。使用文件名创建一个哈希集并改为查找它。

      【讨论】:

        【解决方案5】:

        实际上您并没有使用字符串生成器。您首先通过以下方式创建一个字符串:

        AppDomain.CurrentDomain.BaseDirectory + "Registry\\" + postalCode + ".html"
        

        然后将其提供给字符串生成器。

        正确使用 StringBuilder:

        StringBuilder fileName = new StringBuilder();
        fileName.Append(AppDomain.CurrentDomain.BaseDirectory);
        fileName.Append("Registry\\");
        fileName.Append(postalCode );
        fileName.Append(".html");
        

        如果你用衬垫来制作字符串,你可以通过以下方式制作字符串:

        string filenamestr = AppDomain.CurrentDomain.BaseDirectory + "Registry\\" + postalCode + ".html";
        

        在这种情况下,您正在制作文件路径,因此建议使用:

        Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Registry\\" , postalCode , ".html");
        

        【讨论】:

        • 所以我分配了两个字符串。一个用于将字符串分配给 stringbuilder,另一个用于从 stringbuilder 创建一个字符串。
        • 使用 .Append(string str) 你仍然创建字符串 str,所以优化是值得怀疑的
        • 在这种情况下我不会使用 stringbuilder
        • @enkryptor 你确定 filename.Append 创建了一个新字符串。那怎么用full呢?
        • @Charlie 如果你传递一个必须分配字符串的字符串文字(例如“.html”)。
        【解决方案6】:

        您也可以使用 string.Format。它在内部使用 StringBuilder。

        在你的情况下:

            var fileName = string.Format("{0}Registry\\{1}.html", AppDomain.CurrentDomain.BaseDirectory, postalCode);
        

        Is String.Format as efficient as StringBuilder

        【讨论】:

          【解决方案7】:

          鉴于您的代码所做的(检查文件是否存在),真正的瓶颈不会是使用字符串或字符串生成器,而是检查文件是否真的存在......所以我会让系统进行字符串的连接和照顾表演:

          internal bool isFileExists()
          {
              return System.IO.File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Registry\\" , postalCode , ".html"));
          }
          

          【讨论】:

            猜你喜欢
            • 2011-12-26
            • 2020-07-25
            • 1970-01-01
            • 2011-07-11
            • 2011-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-07
            相关资源
            最近更新 更多