【问题标题】:C# Best way of assigning values to strings in a loopC#在循环中为字符串赋值的最佳方法
【发布时间】:2023-03-11 03:05:01
【问题描述】:

我想知道在循环中分配字符串变量的最有效方法是什么。因此,例如,如果我必须浏览节点列表并将节点的值分配给字符串,如果我在循环开始之前定义一个变量会更好

string myStringVariable = string.Empty
foreach(XmlNode node in givenNodes)
{
    myStringVariable = node.Value;
    ....
    ...
}

或者如果我在循环内定义变量会更有效

foreach(XmlNode node in givenNodes)
{
    string myStringVariable = node.Value;
    ....
    ...
}

我认为第一种方法更有效,而第二种方法看起来更优雅。两者之间有性能差异吗?

感谢您的回答。

【问题讨论】:

  • 也许您可以格式化问题中的源代码部分。标记它并使用“Ctrl + K”或代码示例按钮。

标签: c# .net performance string loops


【解决方案1】:

对于现代编译器,这根本不会产生任何性能差异,您应该始终使用与您的算法最匹配的方式。也就是说,如果您不需要上次迭代中的变量值,则首选第二个变体。

【讨论】:

  • 对不起,事实上你似乎是对的! (取消投票)我总是倾向于忘记编译器优化......
【解决方案2】:

我想主要问题是:您是否需要在代码中的某个位置进一步使用该字符串变量,或者它的使用仅限于 for 循环的范围?如果它仅限于 for 循环的范围,请务必在循环内声明它。我怀疑这两种方式都会有任何性能损失,但这应该是保持变量范围正确的次要因素。

【讨论】:

    【解决方案3】:

    不,两者之间没有真正的性能差异。 VM 将认识到它只需要在堆栈上为一个额外的变量分配空间。

    【讨论】:

      【解决方案4】:

      我通常不会优化到这个级别,因为我希望 JIT 编译器能够在运行时执行这样的优化。话虽如此,我从未真正将两者进行比较。当然,如果您确实需要最大性能,则值得以两种方式进行测试(使用足够数量的迭代和发布版本)。

      【讨论】:

        【解决方案5】:

        事实上,字符串是不可变的,并且 .net 可以使用引用,因此这两种方法之间没有性能差异。

        也许第一个会慢一点,因为有一组(不需要的)myStringVariable 到 string.Empty。但我认为这些问题将由编译器和 JIT 保留,因此两者在性能方面没有区别。

        最后但并非最不重要的是范围有所不同。因此,在需要该变量的适当范围内声明该变量。

        【讨论】:

          【解决方案6】:

          为什么不在控制台应用程序中设置一个小测试并对其进行测试。 这两种方法的结果都非常接近。

          using System;
          using System.Collections.Generic;
          using System.Text;
          using System.Diagnostics;
          
          namespace stringtestloop
          {
              class Program
              {
                  static void Main(string[] args)
                  {
                      Stopwatch w = new Stopwatch();
                      int itterations = 1024 * 1024 * 512;
          
                      w.Start();
                      string var1 = string.Empty;
                      for (var i = 0; i < itterations; i++)
                      {
                          var1 = "some string";
                      }
                      w.Stop();
          
                      Console.WriteLine("outside: {0} ms", w.ElapsedMilliseconds);
          
                      w.Reset();
          
                      w.Start();
                      for (var i = 0; i < itterations; i++)
                      {
                          string var2 = "some string";
                      }
                      w.Stop();
          
                      Console.WriteLine("inside: {0} ms", w.ElapsedMilliseconds);
                      Console.ReadKey();
                  }
              }
          }
          

          编辑:

          下一个要问自己的问题是...... 536870912 (1024*1024*512) 是否与您将要使用的数字相似。如果没有,如果你的数量会少很多,那么你真的不会注意到差异。

          【讨论】:

          • 干杯 Greg,我确实看到了使用您的代码的性能差异。在外部声明时大约需要 1500 毫秒,在内部声明时大约需要 2000 毫秒。
          • 您可能需要仔细检查基准测试,Hamid。像格雷格一样,我得到了非常相似的结果。另外,请注意,如果您编译此版本,它会优化循环体。
          【解决方案7】:

          我怀疑是否存在任何显着的性能差异,因为在这两种情况下,您只是获得对 XmlNode.Value 的引用,而不是创建新字符串。

          不过,您通常不必担心优化这些情况。只需在将要使用的范围内声明变量,然后让编译器发挥它的魔力。

          【讨论】:

            猜你喜欢
            • 2011-12-19
            • 2013-02-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多