2012-07-18 120 views
2

我決定用C#和C++來讀取圖像的基準,以決定在我正在考慮爲自己製作的項目中使用哪種語言。我預計基準與C++的關係可能會非常接近,可能會略微推進。GDI +圖像比C#快得多圖像

C#代碼每次運行大約需要300ms(每次運行100次),其中C++代碼大約需要1.5ms。

那麼我的C#代碼是否錯誤?我的基準測試很糟糕嗎?或者它真的太慢了​​?

這裏的C#代碼我使用:

Stopwatch watch = new Stopwatch(); 

watch.Start(); 
Image image = Image.FromFile(imagePath); 
watch.Stop(); 

Console.WriteLine("DEBUG: {0}", watch.ElapsedMilliseconds); 

以及C++代碼幾乎歸結爲:

QueryPerformanceCounter(&start); 
Image * img = Image::FromFile(imagePath); 
QueryPerformanceCounter(&stop); 
delete img; 
return (stop.QuadPart - start.QuadPart) * 1000.0/freq.QuadPart; 

無論哪種語言,他們需要在一個Image對象落得,因爲它提供了我將需要的功能。

============================================= ==========================

xanatos在註釋中指出,Image.FromFile確實會檢查。

更具體地說,本:

num = SafeNativeMethods.Gdip.GdipImageForceValidation(new HandleRef(null, zero)); 
if (num != 0) 
{ 
    SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(null, zero)); 
    throw SafeNativeMethods.Gdip.StatusException(num); 
} 

使用Image.FromStream()來代替,就可以避免這一點。

我想知道的是,如果你確實避免這一點,並嘗試加載無效的圖像文件,它會引發OutOfMemory異常。
而在C++中,你不要這樣檢查。那麼這個檢查有多重要?任何人都可以給我一個避免這種情況不好的情況嗎?

+0

兩者都以相同的方式做同樣的事情。檢查你使用的方法的內部實現('Image.FromFile'和'Image :: FromFile')。也許有差異。但爲你的需要,因爲你看到'C++'是最好的選擇(如果開發時間不比性能更重要) – Leri 2012-07-18 14:18:15

+0

我希望你在沒有附加調試器的情況下以發佈模式運行你的項目(CTRL + F5) – xanatos 2012-07-18 14:24:59

+0

@xanatos yes當然。 – Josh 2012-07-18 14:28:24

回答

7

是的,你的基準是有缺陷的。問題是,你忘了實際上東西與位圖。像繪畫一樣。

GDI +大大優化了圖像的加載。與.NET優化加載程序集的方式非常相似。它做了必要的事情,它讀取文件的頭部以檢索基本屬性。格式,寬度,高度,Dpi。然後它創建一個內存映射文件來創建映射到文件中的像素數據。但實際上並沒有讀取的像素數據。

現在差​​異就此起作用。下一個System.Drawing.Image實際上讀取像素數據。這會導致頁面錯誤,操作系統現在讀取文件並將像素數據複製到RAM中。非常值得期待的是,如果文件有任何問題,那麼在FromFile()調用中,而不是一段時間後,您會得到一個異常,通常當您的程序繪製圖像並被掩埋在您未寫入的框架代碼中時。 C#代碼的基準標記乘以創建像素數據的mmf

C++程序總是需要爲讀取像素數據付費。但是你沒有衡量這一點,你只測量了創建MMF的成本。

-2

我知道的幾個點

有一種叫做CLR的東西。如果所說的C++框架(看起來是Qt)使用的系統調用不依賴於.net框架,那麼顯然它會運行得很快。

關於c#=>可以在代碼中調用它之前加載該程序集。如果你這樣做,那麼你可以發現它的規模很大。

如果您使用Windows平臺,那麼MS不會降低其自己的語言的執行速度,除非有其他必要性。