为什么C#运行速度比C ++快?

Why is C# running faster than C++?

我不是开玩笑。我有一个C语言应用程序和一个C++应用程序。他们做同样的事情,用同样数量的代码…

…而且C One的运行速度更快,不仅更快,而且比它快10倍。

这让我觉得很奇怪,因为首先,我在调试程序中运行C应用程序,这会减慢C应用程序的运行速度。然后,出于这个原因,C是使用编译成MSIL的.NET和一系列额外功能的开销巨大的字节码,这应该会降低速度。而C++只是纯机器代码。

这是C代码:

1
2
3
4
5
6
7
8
9
static void main()
{
    ulong i = 0;
    while (i < 100000000000)
    {
        Console.WriteLine(i);
        i++;
    }
}

这是C++代码

1
2
3
4
5
6
7
8
9
10
int main()
{
    usigned long i = 0;
    while (i < 100000000000)
    {
        cout << i << endl;
        i++;
    }
    return 0;
}

他们只是在计数和显示一个数字。C++的一个是1000,而C的则是7000。(快7倍)

我甚至尝试编译这两个命令,并在没有调试程序的情况下运行它们,使用命令提示符和命令:cplusplus.exe&;csharp.exe

是的,我知道这个问题可能是"离题":P或者是"不清楚被问到什么"。:但是请有人给我解释一下。

如果这很重要,我使用的CPU是:Inteli7 2.5 GHz。

编辑:我做了一个想法,加上std::ios_base::sync_with_stdio(false);想法,没有任何运气或结果变化。

编辑2:我试过C的printf(),它快得多。比C快3倍。

人们告诉我,IO流是非常慢的,所以我尝试他们都没有写到控制台,和C++仍然明显快于C。

总之,writeline()比cout快得多,printf()比两者都快得多。所以写控制台是唯一能减慢速度的事情。

tldr:printf()获胜,控制台写入速度减慢。


您的代码效率低下,因为:

  • 默认情况下,C++流对象与C的STDIO同步,这使得它很慢。
  • 你用的是endl,这会使速度变慢。

解决了这两个问题,您得到了以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
    std::ios_base::sync_with_stdio(false);

    usigned long i = 0;
    while (i < 100000000000)
    {
        cout << i << '
'
; //use
, not endl
        i++;
    }
    return 0;
}

编译为(必须使用优化标志,无论您使用的是什么编译器):

1
2
$ g++ main.cpp -O3 -o run.test
$ time ./run.test

关于sync_with_stdio(false)endl的解释,请阅读我的回答:

  • Python比C++快吗?这是怎么发生的?

希望有帮助。


我认为你在评价时不够谨慎。我用C++重新创建了你的测试,如下面详细说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSScratch
{
    class Program
    {
        static void Main(string[] args)
        {
            ulong i = 0;
            while (i < 1000000)
            {
                Console.WriteLine(i);
                i++;
            }
        }
    }
}

我在VS2013发布模式中构建了以上的CSScratch.exe,然后(在cygwin bash下)对其进行计时,并将输出重定向,因此不计算文件系统的写入时间。结果相当一致,五次跑步中最快的是:

1
2
3
4
5
time ./CSScratch.exe > NUL

real    0m17.175s
user    0m0.031s
sys     0m0.124s

C++等价:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

int main()
{
    std::ios_base::sync_with_stdio(false);


    unsigned long i = 0;
    while (i < 1000000)
    {
        std::cout << i << '
'
;
        i++;
    }
}

也与VS2013一起编译:

1
2
cl /EHsc /O2 output.cc
time ./output > NUL

五次跑步中最慢的一次:

1
2
3
real    0m1.116s
user    0m0.000s
sys     0m0.109s

它仍然比最快的C跑(17.175秒)快(1.116秒)。

两个版本的某些时间都是通过加载/动态链接、初始化等来完成的。我将C++版本修改为循环10X,但它只花了9.327秒——大约第十的工作量需要的C时间的一半。

(可以通过设置更大的输出缓冲区来进一步调整C++版本,但这不是通常需要的)。


如果你替换

1
cout << i << endl;

具有

1
2
printf("%d
"
, i);

结果将接近.NET WRITELINE。

一般来说,你在C++或C上写的一个事实并不意味着你的代码会更快。快速代码不仅是语言语法。它还需要一些基础知识,如硬件和操作系统内部。

我的意思是正确使用C++提供了更好的结果,至少在不平凡的任务上。


托尼·D在评论中提出了一个很好的观点。将此代码添加到您的C代码中,然后再次计时:

1
2
3
4
5
6
7
8
9
10
static void main()
{
    ulong i = 0;
    while (i < 100000000000)
    {
        Console.WriteLine(i);
        Console.Out.Flush();
        i++;
    }
}