簡體   English   中英

為什么我的C程序比它的C#等效速度慢?

[英]Why is my C program slower than its C# equivalent?

我想在C和C#之間做一個小的基准測試,所以我編寫了以下程序:

C:

int main()
{
    int i = 1;
    while (i <= 500000)
    {
        printf("%d", i);
        i++;
    }
}

C#:

class Program
    {
        static void Main(string[] args)
        {
            int i = 1;
            while (i <= 500000)
            {
                Console.Write(i);
                i++;
            }
        }
    }

然后我編譯它們並同時運行它們。

令我驚訝的是,C#程序比C程序提前了大約5秒。

C是一種以其高速和高性能而聞名的語言,那么在這種情況下,C#程序在如此簡單的任務中能夠顯着優於C程序呢? 我認為C#速度慢得多,因為它在運行時編譯,但它很容易擊敗從C編譯的本機可執行文件。

這是什么原因,這種情況在其他類型的程序中也會發生嗎?

我在Windows 8.1 Pro 64位上運行這兩個程序,如果這很重要,並在C#Express 2010中編譯C#程序,在VS2013 Express for Desktop中編譯C程序。

請不要因為“這么常見的問題”而抨擊我 - 是的,我已經看到了另一個答案,但它們都處理了復雜的事情,如內存管理和緩沖區大小,這里的程序非常簡單,不需要處理那些事情。

我也嘗試用puts替換printf ,但那也很慢。

對編程語言寫入控制台的速度進行基准測試毫無價值。 這是這兩種情況的瓶頸,而且它會搞砸你的結果。 其中一個程序(C或C#版本)的執行時間從一次運行到下一次運行會有很大差異。 因此,兩種語言之間的任何比較都是毫無意義的。

如果你真的想測試性能差異,那么一種方法就是編寫復雜的數學算法並對其進行基准測試。 不要把結果寫到控制台,但是你現在知道這會破壞目的! 此外,請使用高分辨率計時器。 在C#中,你會使用Stopwatch ; 在C中(至少在Windows上),您將調用QueryPerformanceCounter函數 使用真正的秒表計時太容易出錯了。 或者至少它適合我。 無論哪種方式,請確保在您正在測試的代碼之外查詢這些值。

這與C語言或其編譯器沒有任何關系,與其運行時支持庫有關。 減速是由您使用printf()引起的。

C運行時庫(CRT)嚴重陷入困境,為可追溯到20世紀70年代的運行時環境建模。 當程序員使用電傳打字機與計算機交談時,一個具有非常原始操作系統的計算機不支持線程,用英語交談。

運行時環境與現代操作系統非常不匹配,需要相當大的開銷來模擬它。 例如,C語言對Unicode的支持非常差。 因此,您輸出的每個字符串都必須精心轉換為Windows中的本機操作系統字符串格式utf-16。 .NET Framework使用System.String,這是一種在utf-16中編碼的字符串類型。 即使是最低級別,Windows也要求字符串為零終止,就像C字符串需要的那樣。 每個.NET字符串都自動為零終止,即使是那些不用於I / O的字符串。 因此不需要轉換,框架可以直接調用輸出字符串的操作系統函數。

那不是結束的地方。 線程的概念與CRT完全不同,它從未被設計為考慮多線程的分支,例如,修改語言環境或同時編寫文本。 所以CRT充滿了低級鎖定,以實現這一目標。 實際上很少有用的開銷,但必須采用,因為20世紀70年代的運行時模型不會不允許也不會考慮它。

你可以使你的C程序和你的C#程序一樣快,使它顯着更快有點延伸,但你必須繞過20世紀70年代這樣做。 使用wprintf()代替已經應該有明顯的區別,在調用WriteConsoleW()或WriteFile()之前,你不會得到奇偶校驗。

請注意,這實際上並不重要。 無論如何,文本在屏幕上滾動的速度遠遠快於人類可以讀取的速度。 因此,任何人都不會考慮修復這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM