我在.NET中發現了這個奇怪的行爲,甚至在再次調查CLR via C#後,我仍然感到困惑。假設我們有一個接口與一個方法和imlements一類是:C#:爲什麼調用實現的接口方法對於類變量比接口變量更快?
interface IFoo
{
void Do();
}
class TheFoo : IFoo
{
public void Do()
{
//do nothing
}
}
然後我們只想實例化這個類,並把這個DO()方法有很多次在兩個方面:使用混凝土類變量和使用接口變量:
TheFoo foo1 = new TheFoo();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (long i = 0; i < 1000000000; i++)
foo1.Do();
stopwatch.Stop();
Console.Out.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds);
IFoo foo2 = foo1;
stopwatch = new Stopwatch();
stopwatch.Start();
for (long i = 0; i < 1000000000; i++)
foo2.Do();
stopwatch.Stop();
Console.Out.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds);
令人驚訝的(至少對我來說)所經過的時間是大約10%的不同:
Elapsed time: 6005
Elapsed time: 6667
所不同的是不那麼多,所以我會不在大多數情況下,不用擔心這一點。然而,我只是無法弄清楚爲什麼會發生這種情況,即使在查看IL代碼後,如果有人向我指出我明顯缺少的東西,我將不勝感激。
我跑你的測試,我其實有一個非常不同的結果。已用時間:12125年 已用時間:11682。我明顯在較慢的機器上運行。衡量這樣的表現非常困難,因爲有些因素可能並不明確。 –
@克雷格可能你有一些過程受到干擾。我在這個微型基準測試中有10次非常一致的結果。 –
@Ivan我發佈了多次,並獲得一致的結果。我也剛剛去,並重新把它放到一個循環中,並將它連續運行10次。我在機器上運行的很少,我一直看到第一種情況變慢。它現在差不多是2:1。我還添加了另一個明確實現接口並對其進行測試的類。它與第二個案例大致相同。你使用的是什麼版本的框架?也許這會導致差異。 –