通过我昨天发布的一个问题,很明显在循环外声明变量并在循环内实例化它与简单地将声明移动到循环内相比没有性能优势,因此声明和实例化是同时完成的.但是实例化呢?请考虑以下两个选项。
//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
}
就此问题而言,关键假设是:
- p 在循环外不需要
- p 也没有被写入(所以结果明智,两者是相同的)
- 我们应该继续重新实例化 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
实例,则没有合乎逻辑的理由一遍又一遍地实例化它
在循环内。在循环外分配一次并在循环内使用。
关于原始类型,你应该区分值类型(int
、long
、double
)和引用类型(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/