【问题标题】:Why is C# running faster than C++?为什么 C# 运行速度比 C++ 快?
【发布时间】:2015-10-27 15:31:53
【问题描述】:

我不是在开玩笑。 我有一个 C# 应用程序和一个 C++ 应用程序。他们用完全相同的代码量做完全相同的事情......

...而且 C# 的运行速度更快,不仅更快,而且快了 10 倍。

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

这是 C# 代码:

static void main()
{
    ulong i = 0;
    while (i < 100000000000)
    {
        Console.WriteLine(i);
        i++;
    }
}

虽然这是 C++ 代码

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:Intel i7 2.5 Ghz。

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

编辑 2:我尝试了 C 的 printf(),它的速度要快得多。比 C# 快 3 倍。

人们告诉我 IO 流很慢,所以我在没有写入控制台的情况下尝试了它们,C++ 仍然比 C# 快得多。

总之,Writeline() 比 cout 快得多,而 printf() 比两者都快得多。所以写到控制台是唯一减慢它的东西。

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

【问题讨论】:

  • 您的程序受 I/O 限制,因此您实际上是在比较两个运行时的 I/O 堆栈,而不是语言。
  • 另外,您是否在发布模式下编译了您的 C++? iostreams 有大量的间接性,随着优化的开启,这些间接性会大大减少。
  • 您如何对它们进行基准测试?我相信 C# 的 WriteLine 不会在每一行之后刷新如果从控制台重定向,而在 C++ 中 endl 明确地请求刷新,不管......
  • 大声笑,这不是“应用程序”,它只是一些 API 上的小客户端,看起来它做同样的事情,但很大程度上取决于内部配置标志。完全相同的问题已经在这里发布了。
  • 抱歉,我混淆了一个与 Python 相关的问题。但老实说,足够相似,足以建立大脑连接。 stackoverflow.com/questions/9371238/…

标签: c# c++ performance


【解决方案1】:

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

  • 默认情况下,C++ 流对象与 C 的 stdio 同步,这使其速度变慢。
  • 您正在使用endl,这进一步使其变慢。

解决这两个问题,您就拥有了以下代码:

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

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

将此编译为(无论您使用何种编译器都必须使用优化标志):

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

有关sync_with_stdio(false) 和endl 的解释,请在此处阅读我的答案:

希望对您有所帮助。

【讨论】:

  • 根据我的经验,sync_with_stdio 是一个红鲱鱼。无论您使用什么标志,I/O 流性能本质上都很糟糕。
  • @t.c.这就像一个放大器上的 11。
  • 当您退后一步时,现在在我看来,可能 OP 实际上是在尝试测量程序的 i++ 部分,但没有意识到输出所产生的开销是瓶颈?这将我带到下一个问题,删除输出将使优化器完全摆脱循环。即使在最后打印它,编译器也可以直接准备结果。这就是为什么我在上面说“这不是一个应用程序”。
  • I/O 流本身就很慢,毫无疑问,但sync_with_stdio 进一步使其变慢。请尝试一下。
【解决方案2】:

我认为您在评估时不够谨慎。我用 C++ 重新创建了你的测试,证明速度大大加快,详情如下:

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 Release 模式下将上述内容构建到 CSScratch.exe,然后我对它进行计时(在 cygwin bash 下)并重定向输出,因此不计算文件系统写入时间。结果相当一致,五次运行中最快的是:

time ./CSScratch.exe > NUL

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

C++ 等价物:

#include <iostream>

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


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

同样用VS2013编译:

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

五次运行中最慢的:

real    0m1.116s
user    0m0.000s
sys     0m0.109s

这仍然比最快的 C# 运行速度(1.116 秒)更快(17.175 秒)。

两个版本的一些时间都花在了加载/动态链接、初始化等方面。我将 C++ 版本修改为 循环 10 倍以上,但它仍然只是耗时 9.327 秒 - 大约是 C# 完成十分之一工作负载所需时间的一半。

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

【讨论】:

    【解决方案3】:

    Tony D 对 cme​​ts 中的缓冲提出了一个很好的观点。
    将此添加到您的 C# 代码中并再次计时:

    static void main()
    {
        ulong i = 0;
        while (i < 100000000000)
        {
            Console.WriteLine(i);
            Console.Out.Flush();
            i++;
        }
    }
    

    【讨论】:

      【解决方案4】:

      如果你替换

      cout << i << endl;
      

      与

      printf("%d\n", i);
      

      结果将接近 .net WriteLine。

      一般来说,您使用 C++ 或 C 编写的事实并不自动意味着您的代码会更快。快速代码不仅是语言语法。它还需要一些底层知识,如硬件和操作系统内部。

      我的意思是正确使用 C++ 会产生更好的结果,至少在不平凡的任务上是这样。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-27
        • 2012-03-29
        • 2010-10-10
        • 2014-10-09
        • 2012-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多