还是现在反过来了?

据我所知,c#在某些领域被证明比c++更快,但我从来没有勇气亲自测试它。

我想你们任何人都可以详细解释这些差异,或者告诉我有关信息的正确位置。


当前回答

毕竟,答案总要在某个地方,不是吗?:)

嗯,没有。

正如一些回复所指出的那样,这个问题在某种程度上没有得到充分的说明,只会引起问题的回应,而不是答案。只从一个方面来说:

这个问题将语言和语言实现合并在一起——这个C程序比c#程序慢2194倍,快1.17倍——我们不得不问你:哪种语言实现?

然后是哪些项目?哪个机器?哪些操作系统?哪个数据集?

其他回答

对于图形来说,标准的c#图形类比通过C/ c++访问的GDI慢得多。 我知道这与语言本身无关,更多的是与整个。net平台有关,但是图形是作为GDI替代品提供给开发人员的,它的性能非常糟糕,我甚至不敢用它来处理图形。

我们有一个简单的基准来查看图形库的速度,那就是在窗口中随机绘制线条。c++ /GDI在处理10000行代码时仍然很灵活,而c# /Graphics在处理1000行代码时却很难做到。

需要大量内存访问的应用程序。图像处理通常更适合在非托管环境(c++)而不是托管环境(c#)中编写。使用指针算法优化的内循环在c++中更容易控制。在c#中,你可能需要使用不安全的代码来获得相同的性能。

首先,我不同意这个问题的部分公认答案(并且得到了好评),我说:

为什么jit代码比适当优化的c++(或其他没有运行时开销的语言)运行得慢,实际上有很多原因。 程序包括:

根据定义,在运行时用于jit代码的计算周期在程序执行中不可用。 JITter中的任何热路径都将与你的代码竞争指令和CPU中的数据缓存。我们知道缓存在性能方面占主导地位,而像c++这样的原生语言在设计上并没有这种类型的争用。 运行时优化器的时间预算必然比编译时优化器的时间预算更有限(正如另一个评论者指出的那样)。

底线:最终,您几乎肯定能够在c++中创建比在c#中更快的实现。

现在,说了这么多,速度到底有多快是无法量化的,因为有太多的变量:任务、问题领域、硬件、实现质量和许多其他因素。您将在您的场景上运行测试,以确定性能上的差异,然后决定是否值得额外的努力和复杂性。

这是一个很长很复杂的话题,但为了完整起见,我觉得值得一提的是,c#的运行时优化器非常出色,能够在运行时执行某些c++编译时(静态)优化器无法实现的动态优化。即便如此,优势仍然主要体现在本机应用程序方面,但动态优化器是上面给出的“几乎肯定”限定符的原因。

--

在相对性能方面,我也被我在其他一些答案中看到的数字和讨论所困扰,所以我想我应该插话,同时为我上面所做的陈述提供一些支持。

这些基准测试的很大一部分问题是,你不能像写c#一样写c++代码,并期望得到具有代表性的结果(例如。在c++中执行成千上万的内存分配将会给你可怕的数字。)

相反,我编写了稍微更习惯的c++代码,并与@Wiory提供的c#代码进行了比较。我对c++代码所做的两个主要更改是:

使用向量::储备() 将2d数组平摊到1d以获得更好的缓存位置(连续块)

c#(。净4.6.1)

private static void TestArray()
{
    const int rows = 5000;
    const int columns = 9000;
    DateTime t1 = System.DateTime.Now;
    double[][] arr = new double[rows][];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    DateTime t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

    t1 = System.DateTime.Now;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i;
    t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);
}

运行时间(发布):初始:124ms,填充:165ms

C++14 (Clang v3.8/C2)

#include <iostream>
#include <vector>

auto TestSuite::ColMajorArray()
{
    constexpr size_t ROWS = 5000;
    constexpr size_t COLS = 9000;

    auto initStart = std::chrono::steady_clock::now();

    auto arr = std::vector<double>();
    arr.reserve(ROWS * COLS);

    auto initFinish = std::chrono::steady_clock::now();
    auto initTime = std::chrono::duration_cast<std::chrono::microseconds>(initFinish - initStart);

    auto fillStart = std::chrono::steady_clock::now();

    for(auto i = 0, r = 0; r < ROWS; ++r)
    {
        for (auto c = 0; c < COLS; ++c)
        {
            arr[i++] = static_cast<double>(r * c);
        }
    }

    auto fillFinish = std::chrono::steady_clock::now();
    auto fillTime = std::chrono::duration_cast<std::chrono::milliseconds>(fillFinish - fillStart);

    return std::make_pair(initTime, fillTime);
}

运行时间(发布):初始:398µs(是的,这是微秒),填充:152ms

总运行时间:c#: 289毫秒,c++ 152毫秒(大约快90%)

观察

Changing the C# implementation to the same 1d array implementation yielded Init: 40ms, Fill: 171ms, Total: 211ms (C++ was still almost 40% faster). It is much harder to design and write "fast" code in C++ than it is to write "regular" code in either language. It's (perhaps) astonishingly easy to get poor performance in C++; we saw that with unreserved vectors performance. And there are lots of pitfalls like this. C#'s performance is rather amazing when you consider all that is going on at runtime. And that performance is comparatively easy to access. More anecdotal data comparing the performance of C++ and C#: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore

归根结底,c++为您提供了对性能的更多控制。你想用指针吗?一个参考吗?栈内存?堆吗?动态多态还是用静态多态(通过模板/CRTP)消除虚表的运行时开销?在c++中你必须…呃,自己做出所有这些选择(甚至更多),理想情况下,这样你的解决方案才能最好地解决你正在处理的问题。

问问自己是否真的想要或需要该控件,因为即使对于上面的简单示例,您也可以看到尽管性能有了显著的改进,但它需要更深入的投资才能访问。

我发现2020年4月读过:https://www.quora.com/Why-is-C-so-slow-compared-to-Python,作者是一位拥有15年以上软件开发经验的现实世界的程序员。

它指出,c#通常较慢,因为它被编译为公共中间语言(CIL),而不是像c++那样的机器代码。然后,CIL通过公共语言运行库(CLR)输出机器代码。但是,如果您继续执行c#,它将获取机器代码的输出并缓存它,以便为下次执行保存机器代码。总而言之,如果多次执行,c#会更快,因为它是多次执行后的机器代码。

也有评论说,一个优秀的c++程序员可以做一些耗时的优化,但最终会被优化。

快了5个橘子。或者更确切地说:不可能有一个(正确的)笼统的答案。c++是一种静态编译语言(但也有配置文件引导的优化),c#在JIT编译器的帮助下运行。它们之间的差异如此之大,以至于像“快了多少”这样的问题都无法回答,甚至无法给出数量级。