2013-05-01 80 views
0

我正在閱讀Jon Skeet的優秀書籍C# In Depth。他在關於裝箱和拆箱的部分中提到,使用盒裝物品的開銷很小,可以在一個足夠大的規模上實現性能差異。數值類型與參考類型 - 性能

因此,我編寫了自己的基準測試,使用for循環將所有數字從1增加到100,000,000。在一種情況下,我使用Int32,然後int,然後我投到object並退回到int。重複所有測試10次並取平均值。結果(以秒計):

的Int32平均:0.333

INT平均:0.326

對象平均:Int32int之間1.061

沒有太大的差別,但拳擊/拆箱花了3倍!

所以請幫我理解一下:當你投intobject時,是不是和把它投到Int32一樣? DotNetPerls聲稱int實際上只是Int32的別名 - 但是如果是這種情況,那麼爲什麼int始終以比Int32更快的速度執行,即使只是略微如此?

編輯:徇衆要求,這裏的基準代碼:

const int SIZE = 100000000, ITERATIONS=10; 
var intTimes = new List<double>(); 
var int32Times = new List<double>(); 
var objectTimes = new List<double>(); 

for (var n = 0; n < ITERATIONS; n++) 
{ 
    Console.WriteLine("Iteration "+(n+1)); 
    Console.WriteLine("Testing using Int32"); 
    long result = 0; 
    var sw = Stopwatch.StartNew(); 
    for (Int32 x = 0; x < SIZE; x++) 
    { 
     result += x; 
    } 
    sw.Stop(); 
    int32Times.Add(sw.Elapsed.TotalSeconds); 
    Console.WriteLine("Result = {0} after {1:0.000} seconds", result, sw.Elapsed.TotalSeconds); 

    Console.WriteLine("Testing using int"); 
    result = 0; 
    sw = Stopwatch.StartNew(); 
    for (int x = 0; x < SIZE; x++) 
    { 
     result += x; 
    } 
    sw.Stop(); 
    Console.WriteLine("Result = {0} after {1:0.000} seconds", result, sw.Elapsed.TotalSeconds); 
    intTimes.Add(sw.Elapsed.TotalSeconds); 

    Console.WriteLine("Testing using object"); 
    result = 0; 
    sw = Stopwatch.StartNew(); 
    for (int i = 0; i < SIZE; i++) 
    { 
     object o = i; 
     result += (int) o; 
    } 
    sw.Stop(); 
    Console.WriteLine("Result = {0} after {1:0.000} seconds", result, sw.Elapsed.TotalSeconds); 
    objectTimes.Add(sw.Elapsed.TotalSeconds); 
} 
Console.WriteLine("Summary:"); 
Console.WriteLine("Int32 avg: {0:0.000}", int32Times.Average()); 
Console.WriteLine("int avg: {0:0.000}", intTimes.Average()); 
Console.WriteLine("object avg: {0:0.000}", objectTimes.Average()); 
+3

我們將不得不看你的測試。最有可能的是你沒有讓抖動變得溫暖,所以你的第一個人的表現會比第二個人慢。 – 2013-05-01 17:42:00

+0

@KirkWoll基準代碼添加到問題。 – 2013-05-01 18:00:30

回答

3

C#的關鍵字intSystem.Int32的別名。所以執行完全一樣。

當然,測量過程中總會有波動,因爲您的機器也在執行其他任務。

每次將int轉換爲object時,只留下一小部分內存(在堆上),並將int的值複製到那裏。這需要很多努力。每次你將它拋出去,比.NET首先檢查你的對象是否實際上包含了一個int(因爲一個對象可以包含任何東西),然後將值複製回int。這項檢查也需要時間。

+0

我跑了幾次基準;每次'int'循環比'Int32'循環快,在1-5%之間。你認爲那只是巧合? – 2013-05-01 17:43:05

+1

這是你正在運行的一個程序做三個測試還是你修改程序併爲一個數據類型運行一個測試? – 2013-05-01 17:44:13

+1

@Shaul它必須是巧合(或測試代碼中的缺陷)。 'int'和'System.Int32'是*同義詞*。他們將產生相同的IL代碼(您可以使用Reflector進行驗證)。 – 2013-05-01 17:52:43