C#为循环中的字符串赋值的最佳方法

时间:2022-05-21 01:38:32

I wonder what is the most efficient way of assigning string variables in a loop. So, for example if I have to browse through a list of nodes and assigning the value of the node to a string, would it be better if I define a variable before the loop starts like

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

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

or would it be more efficient if I define the variable inside the loop like

或者如果我在循环中定义变量就更有效率了

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

I think the first approach is more efficient while the second looks more elegant. Is there a performance difference between the two?

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

Thanks for you answers.

谢谢你的回答。

7 个解决方案

#1


With modern compilers this doesn't make any performance difference at all and you should always use the way that best matches your algorithm. That is, prefer the second variant if you don't need the variable's value from the last iteration.

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

#2


I guess the main question is: do you need to use that string variable further down in your code somewhere, or is its use limited to the scope of the for loop? If it's limited to the scope of the for loop, definitely declare it inside the loop. I doubt there's any performance penalty for doing it either way, but that should be secondary to keeping your variables scoped properly.

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

#3


Nope, there is no real performance difference between the two. The VM will recognize that it only needs to allocate space on the stack for one additional variable.

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

#4


I don't usually optimize to this level, because I'd expect the JIT compiler to be able to perform an optimization like that anyway at runtime. That being said, I've never actually compared the two. Of course, if you really do need the maximum performance, it's worth testing it both ways (using a sufficent number of iterations and with a release build).

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

#5


Due to fact, that strings are immutable and .net works with references, there is no performance difference between both methods.

事实上,该字符串是不可变的,.net与引用一起使用,两种方法之间没有性能差异。

Maybe the first one would be a little bit slower, cause there is one (unneeded) set of myStringVariable to string.Empty. But i think these issues will be kept by compiler and JIT and so there is no difference between both in case of performance.

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

Last but not least there is a difference in scope. So declare the variable in the appropriate scope, where the variable is needed.

最后但并非最不重要的是,范围存在差异。因此,在需要变量的适当范围内声明变量。

#6


Why don't you set up a little test in a console application and test it. I get very close results for both methods.

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

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();
        }
    }
}

EDIT:

The next question to ask yourself is... Is 536870912 (1024*1024*512) a similar number to what you are going to be working with. If not, if your number is going to be a lot less, then you really aren't going to notice the difference.

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

#7


I doubt there is any significant performance difference, since in both cases you're just getting a reference to the XmlNode.Value, not creating a new string.

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

Still, you usually shouldn't worry about optimizing these cases. Just declare the variable in the scope it's going to be used and let the compiler work its magic.

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

#1


With modern compilers this doesn't make any performance difference at all and you should always use the way that best matches your algorithm. That is, prefer the second variant if you don't need the variable's value from the last iteration.

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

#2


I guess the main question is: do you need to use that string variable further down in your code somewhere, or is its use limited to the scope of the for loop? If it's limited to the scope of the for loop, definitely declare it inside the loop. I doubt there's any performance penalty for doing it either way, but that should be secondary to keeping your variables scoped properly.

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

#3


Nope, there is no real performance difference between the two. The VM will recognize that it only needs to allocate space on the stack for one additional variable.

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

#4


I don't usually optimize to this level, because I'd expect the JIT compiler to be able to perform an optimization like that anyway at runtime. That being said, I've never actually compared the two. Of course, if you really do need the maximum performance, it's worth testing it both ways (using a sufficent number of iterations and with a release build).

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

#5


Due to fact, that strings are immutable and .net works with references, there is no performance difference between both methods.

事实上,该字符串是不可变的,.net与引用一起使用,两种方法之间没有性能差异。

Maybe the first one would be a little bit slower, cause there is one (unneeded) set of myStringVariable to string.Empty. But i think these issues will be kept by compiler and JIT and so there is no difference between both in case of performance.

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

Last but not least there is a difference in scope. So declare the variable in the appropriate scope, where the variable is needed.

最后但并非最不重要的是,范围存在差异。因此,在需要变量的适当范围内声明变量。

#6


Why don't you set up a little test in a console application and test it. I get very close results for both methods.

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

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();
        }
    }
}

EDIT:

The next question to ask yourself is... Is 536870912 (1024*1024*512) a similar number to what you are going to be working with. If not, if your number is going to be a lot less, then you really aren't going to notice the difference.

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

#7


I doubt there is any significant performance difference, since in both cases you're just getting a reference to the XmlNode.Value, not creating a new string.

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

Still, you usually shouldn't worry about optimizing these cases. Just declare the variable in the scope it's going to be used and let the compiler work its magic.

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