繁体   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