c#,在for中声明一个变量.循环,它会降低性能吗?

本文关键字:循环 性能 变量 for 声明 一个 | 更新日期: 2023-09-27 18:12:22

例如:

            for (i = 0; i < 100; i++)
            {
               string myvar = "";
                // Some logic
            }

是否使性能或内存泄漏?

为什么我这样做,因为我不希望"myvar"可以在for..循环之外访问。

它是任何性能监视器,我可以比较两个片段或整个程序之间的执行时间?

谢谢你。

c#,在for中声明一个变量.循环,它会降低性能吗?

不,变量纯粹是为了程序员的方便。在哪里申报并不重要。

也许你可以看看我曾经做过的一个关于另一个对话的老测试。变量声明。优化方法

结果表明,重新定义更快,但在内存上不那么容易。

我的简单测试。我初始化一个对象100,000,000次,显然创建一个新对象比重用一个旧对象要快得多:O

    string output = "";
    {
        DateTime startTime1 = DateTime.Now;
        myclass cls = new myclass();
        for (int i = 0; i < 100000000; i++)
        {
            cls = new myclass();
            cls.var1 = 1;
        }
        TimeSpan span1 = DateTime.Now - startTime1;
        output += span1.ToString();
    }
    {
        DateTime startTime2 = DateTime.Now;
        for (int i = 0; i < 100000000; i++)
        {
            myclass cls = new myclass();
            cls.var1 = 1;
        }
        TimeSpan span2 = DateTime.Now - startTime2;
        output += Environment.NewLine + span2.ToString() ;
    }
    //Span1 took 00:00:02.0391166
    //Span2 took 00:00:01.9331106
public class myclass
{
    public int var1 = 0;
    public myclass()
    {
    }
}

我认为这将是一个性能问题。因为VM需要分配内存来存储每个循环对String的引用。即使引用可能指向同一个String实例,每次循环时都分配内存也不可取。

UPDATE:

如果你使用与循环相同类型的变量,你可以按照我最初的建议:

for (int  i = 0,  myvar = 0; i < 100; i++) {
    //some logic
}

否则就不用像别人建议的那样担心了

@phoog,谢谢你检查答案

提供一个真实的例子:

我刚刚写完一个。obj模型加载器,当然,它包含一些嵌套循环。我在我的循环上面声明了我所有的变量,但后来我开始想知道和OP一样的事情,发现了这个线程。因此,我尝试将所有变量声明移动到循环中使用它们的第一个点,并且实际上看到了一点性能增益。以前加载平均耗时380毫秒(实际上是370-400毫秒)的模型现在加载速度持续提高了15-20毫秒。这仅仅是5%,但仍然是一个进步。

我的循环结构只包含一个foreach循环和一个嵌套的for循环,但也包含许多if语句。我移动了5个变量声明,其中大多数是字符串和整型数组。

是的,这会产生内存使用问题。我不认为它会导致内存泄漏,因为垃圾收集器最终会收集未使用的对象,但这将对应用程序的性能产生负面影响。

我建议您使用在for循环作用域之外声明的字符串构建器

它不会降低性能或导致内存泄漏,但仍然需要注意。

字符串是不可变的,这意味着一旦创建,它们就不能被更改。通过在循环中创建一个新的字符串,您至少创建了n个字符串变量。如果你想在循环中做字符串操作,你应该考虑使用StringBuilder

除非编译器以某种方式优化了您的代码,否则在for循环中声明变量将需要分配新变量和收集旧变量。也就是说,编译器在优化代码方面确实做得很好。

如果您想要一种快速的方法来测试您的两个场景,请使用StopWatch类来测量执行每个场景所需的时间。我的猜测是,这个差异将不存在到可以忽略不计。