【问题标题】:Concatenate multiple strings versus String.Format [duplicate]连接多个字符串与 String.Format [重复]
【发布时间】:2014-04-07 02:50:06
【问题描述】:

这里有两种结果相同的方法:

public class MessageManager
{
    public void SendMessage(string name, int count)
    {
        string message = "Hi " + name + ". I know you don't like cake, so I bought you " + count + " lollipops. Same thing, right?"; // No boxing. "count" was converted to string somehow.
        //Console.WriteLine(message);
    }
    public void SendMessage2(string name, int count)
    {
        string message = String.Format("Hi {0}. I know you don't like cake, so I bought you {1} lollipops. Same thing, right?", name, count); // Boxing "name" and "count" + executing unnecessary code.
        //Console.WriteLine(message);
    }
}

所以我猜第二种方法会比第一种方法慢,因为装箱和执行 String.Format() 方法中的一些额外代码。

我用以下方法测试过它们:

public static class PerformanceTester
{
    public static TimeSpan TestAction(Action<string, int> action)
    {
        Stopwatch timer = new Stopwatch();
        timer.Start();
        for (ushort i = 0; i < ushort.MaxValue; i++)
            action("Alex", 1000);
        timer.Stop();
        return timer.Elapsed;
    }
}

这是它的用法:

    static void Main(string[] args)
    {
        MessageManager mm = new MessageManager();

        TimeSpan ts_m1 = PerformanceTester.TestAction(new Action<string, int>(mm.SendMessage));
        TimeSpan ts_m2 = PerformanceTester.TestAction(new Action<string, int>(mm.SendMessage2));

        Console.WriteLine("First message took time: " + ts_m1.ToString());
        Console.WriteLine("Second message took time: " + ts_m2.ToString());

        Console.ReadKey();
    }

使用我的英特尔® 酷睿™2 双核处理器 E8200(调试)的输出:

使用我的英特尔® 酷睿™2 双核处理器 E8200(发布)的输出:

我看到 String.Format 几乎无处不在(指南、博客、教程等),但它实际上比简单的字符串连接要慢。我知道当我谈论 C# 时,我一定不会关心性能,但是这个例子中的结果太棒了。 问题是:“是否有任何最佳实践,String.Format 实际上比字符串串联更好。”

【问题讨论】:

  • 它是发布版本吗?如果是这样,csc不会对其进行优化并删除完全没有任何副作用的代码吗?
  • 字符串连接是最快的,但会消耗一些内存。 String.format 代码很难阅读(如果您考虑代码的可读性)。这实际上是您想要实现的目标。你必须为另一个妥协。这里有很好的讨论michaelmerrell.com/2011/11/…
  • @zerkms 它正在调试。我现在也添加了版本。
  • @Pierre-LucPineault 在那里找不到我的问题的答案。问题是:“是否有任何最佳实践 String.Format 实际上比字符串串联更好。”
  • @Wallstrider 如果您想要最佳实践,请使用Code Review

标签: c# string


【解决方案1】:

这主要是风格问题。但是,请考虑更复杂的格式。例如你想格式化一堆东西:

var s = String.Format("{0,10:N2}  {1,-20}  {2:P2}", val, description, (val/100));

或者……

var s = val.ToString("10:N2") + string.Format("{0,-20}", desc) + (val/100).ToString("P2");

我更喜欢String.Format 那里的电话。它将格式与内容分开,就像 CSS 将表示与 HTML 内容分开一样。当我编写或检查格式化输出的代码时,我通常希望对格式一目了然。当我调试格式问题时,被格式化的实际值不相关。

通过连接,我必须通过各个值来查看每个项目的格式。

最后,性能真的很重要吗?大多数程序花费很少的时间来格式化它们的输出。优化格式化代码似乎是在浪费时间。写任何更容易维护和证明正确的东西。

【讨论】:

    【解决方案2】:

    string.format 顾名思义,用于格式化字符串。您可以获取格式字符串并将其粘贴到资源中或进行翻译。这与性能无关,也与可读性无关。如果你说小于 5,简单的字符串连接是可以的。如果你想连接更多的字符串并考虑性能 - 使用 StringBuilder。

    【讨论】:

    • 我想你会发现像 OP 显示的那些编译时连接表达式被解析为对 String.Concat 的调用,这“做正确的事”。在内部,它使用StringBuilder。查看String.Concat的参考来源
    • +1 表示翻译评论。我没有考虑过的事情。
    • @JimMischel 感谢您的链接。不知道框架的源码存在。
    猜你喜欢
    • 2013-06-28
    • 2016-01-22
    • 2018-02-20
    • 2010-10-29
    • 2013-08-29
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    相关资源
    最近更新 更多