我在c#中有三个运行相同代码但有一点差别的方法,我的第一个代码块是
Stopwatch s = new Stopwatch();
object o = new object();
s.Start();
for (int i = 0; i < 100000000; i++)
{
o.ToString();
o.GetType();
o.GetHashCode();
}
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds); //3100ms
这需要3100毫秒才能运行。然后,如果我将对象初始化内容的内容增加到7200ms,我的代码块就像这样;
Stopwatch s = new Stopwatch();
s.Start();
for (int i = 0; i < 100000000; i++)
{
object o = new object();
o.ToString();
o.GetType();
o.GetHashCode();
}
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);//7200ms
但是,如果我初始化我的对象但不使用任何方法,这个成本为652ms。我的代码就像这个,
Stopwatch s = new Stopwatch();
s.Start();
for (int i = 0; i < 100000000; i++)
{
object o = new object();
}
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);//625ms
所以我想知道,3100ms + 625ms与7200ms无法比较。是什么导致前两者之间的差异很大?
答案 0 :(得分:3)
在你的第二个区块中,你在许多新对象上调用GetHashCode()
。根据我的记忆,第一次在对象上调用未重写的GetHashCode()
方法时,会为该对象分配一个同步块。这是相对昂贵的,虽然后续调用GetHashCode
同一个对象(根据你的第一个代码)是便宜的。
因此有三点需要注意:
这当然是一种概括 - 许多方法花费相同的时间,无论你多少次调用它们,而其他方法可能比前10次调用慢,之后很快。我认为,在GetHashCode()
的情况下,它的“首次通话是昂贵的”领域。尝试使用以某种简单方式覆盖GetHashCode()
的类型,我怀疑你会发现时间一落千丈。
此外,GetType()
可能需要一段时间才能在第一次调用时为Type
构建object
- 我不确定。基本上你在这里一起测量一堆不同的东西,这总是导致难以分析。
答案 1 :(得分:0)
我会用Refactor或类似的东西反编译方法,看看生成的IL。可能答案就在那里。