c# - 变量范围 : Instantiation Inside or Outside Loop

标签 c# .net performance instantiation

通过我昨天发布的一个问题,很明显在循环外声明变量并在循环内实例化它与简单地将声明移动到循环内相比没有性能优势,因此声明和实例化是同时完成的.但是实例化呢?请考虑以下两个选项。

//OPTION 1:
while (_doWork)
{
    Person p = new Person(name = "John", age = 35);
    //work that involves reading (not writing to) p
}

//OPTION 2:
Person p = new Person(name = "John", age = 35);
while (_doWork)
{
    //work that involves reading (not writing to) p
}

就此问题而言,关键假设是:

  1. p 在循环外不需要
  2. p 也没有被写入(所以结果明智,两者是相同的)
  3. 我们应该继续重新实例化 p(p 在两个选项中看起来相同)没有结果原因

问题:哪个性能更好,哪个选项更适合实践?

这篇文章的答案(尽管是关于声明,而不是实例化)似乎表明后者:Declaring variables inside or outside of a loop

我的想法:

  • 对我来说,继续重新实例化它似乎是一种重大浪费。对于基本类型可能没问题,但对于复杂类?
  • int a = 0 与 int a = new int() 相同,所以我想上面的答案也适用于基本类型?

最佳答案

Which is better performance wise, and which option is better practice?

根据您的问题,如果只需要一个 Person 实例,则没有合乎逻辑的理由一遍又一遍地实例化它 在循环内。在循环外分配一次并在循环内使用。

关于原始类型,你应该区分值类型(intlongdouble)和引用类型(string)。值类型分配在栈上,而引用类型分配在堆上。因此,对于您的 Person 类,我们必须在堆内分配适当数量的字节,而在堆栈上分配 int 是更快的分配。

除了最佳实践之外,如果您想知道两者中哪一个具有更好的性能,请对您的代码进行基准测试。这是在我的英特尔酷睿 i5 M430 上使用 .NET Framework 4.5、VS2013 在 Debug模式下运行的输出:

public class Person
{
    public Person(string name, int age)
    {
        Age = age;
        Name = name;
    }

    public int Age { get; set; }
    public string Name { get; set; }
}

private static void Main(string[] args)
{
   Stopwatch sw = new Stopwatch();
   sw.Start();
   for (int i = 0; i < 1000000; i++)
   {
      Person p = new Person("John", 35);
      var age = p.Age;
      var name = p.Name;
   }

   Console.WriteLine("Loop with inner allocation took {0}", m sw.Elapsed);

   sw.Restart();
   Person px = new Person("John", 35);

   for (int i = 0; i < 1000000; i++)
   {
      var age = px.Age;
      var name = px.Name;
   }

   Console.WriteLine("Loop with outter allocation took {0}", sw.Elapsed)
}

结果:

Loop with inner allocation took 00:00:00.0708861
Loop with outter allocation took 00:00:00.0155522

关于c# - 变量范围 : Instantiation Inside or Outside Loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25443156/

相关文章:

c# - E00114 在 Authorize.net 中使用接受 JS 创建带有付款随机数的订阅时无效的 OTS token

.net - 如何获取FaultException的完整调用堆栈

python - 与它们的等效函数相比,python 类慢了多少?

c# - 在 XNA 4 中绘制行进距离

c# - Azure Custom Vision是否可以分析视频流并计算车辆的车轮数

c# - Dapper 结果到 json(使用 fastjson)

vb.net - 对于 CPU 绑定(bind)进程,VB.NET 是否比 VB6 提供了任何性能改进?

ios - 使用相同图像绘制缓慢

c# - 无法写入 SharePoint 2010 下的 ULS 日志

.net - Microsoft 何时终止对现有版本 .NET Framework 的主流支持?