还是现在反过来了?
据我所知,c#在某些领域被证明比c++更快,但我从来没有勇气亲自测试它。
我想你们任何人都可以详细解释这些差异,或者告诉我有关信息的正确位置。
还是现在反过来了?
据我所知,c#在某些领域被证明比c++更快,但我从来没有勇气亲自测试它。
我想你们任何人都可以详细解释这些差异,或者告诉我有关信息的正确位置。
当前回答
我已经在c++和c#等效中测试了vector - List和简单的2d数组。
我使用Visual c# / c++ 2010 Express版本。这两个项目都是简单的控制台应用程序,我在标准(没有自定义设置)发布和调试模式下对它们进行了测试。 c#列表在我的电脑上运行得更快,c#中的数组初始化也更快,数学运算更慢。
我使用英特尔Core2Duo P8600@2.4GHz, c# - . net 4.0。
我知道向量实现不同于c#列表,但我只是想测试我将用于存储我的对象的集合(并能够使用索引访问器)。
当然,您需要清除内存(比如每次使用new时),但我希望保持代码简单。
c++矢量测试:
static void TestVector()
{
clock_t start,finish;
start=clock();
vector<vector<double>> myList=vector<vector<double>>();
int i=0;
for( i=0; i<500; i++)
{
myList.push_back(vector<double>());
for(int j=0;j<50000;j++)
myList[i].push_back(j+i);
}
finish=clock();
cout<<(finish-start)<<endl;
cout<<(double(finish - start)/CLOCKS_PER_SEC);
}
c#列表测试:
private static void TestVector()
{
DateTime t1 = System.DateTime.Now;
List<List<double>> myList = new List<List<double>>();
int i = 0;
for (i = 0; i < 500; i++)
{
myList.Add(new List<double>());
for (int j = 0; j < 50000; j++)
myList[i].Add(j *i);
}
DateTime t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
}
c++ -数组:
static void TestArray()
{
cout << "Normal array test:" << endl;
const int rows = 5000;
const int columns = 9000;
clock_t start, finish;
start = clock();
double** arr = new double*[rows];
for (int i = 0; i < rows; i++)
arr[i] = new double[columns];
finish = clock();
cout << (finish - start) << endl;
start = clock();
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
arr[i][j] = i * j;
finish = clock();
cout << (finish - start) << endl;
}
c# -数组:
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 * j;
t2 = System.DateTime.Now;
Console.WriteLine(t2 - t1);
}
时间:(发布/调试)
C++
600 / 606 ms array init 200 / 270毫秒阵列填充, 1秒/13秒矢量初始化和填充。
(是的,13秒,我总是在调试模式下遇到列表/向量的问题。)
C#:
20 / 20 ms数组初始化 403 / 440毫秒阵列填充, 710 / 742 ms列表初始化和填充。
其他回答
在一个特殊的场景中,c++仍然占据上风(并且将在未来几年占据上风),即可以在编译时预先确定多态决策。
通常,封装和延迟决策是一件好事,因为它使代码更加动态,更容易适应不断变化的需求,并且更容易作为框架使用。这就是为什么在c#中面向对象编程是非常高效的,并且它可以在术语“泛化”下泛化。不幸的是,这种特殊的泛化在运行时是有代价的。
Usually, this cost is non-substantial but there are applications where the overhead of virtual method calls and object creation can make a difference (especially since virtual methods prevent other optimizations such as method call inlining). This is where C++ has a huge advantage because you can use templates to achieve a different kind of generalization which has no impact on runtime but isn't necessarily any less polymorphic than OOP. In fact, all of the mechanisms that constitute OOP can be modelled using only template techniques and compile-time resolution.
在这种情况下(不可否认,它们通常局限于特殊的问题领域),c++胜过c#和类似的语言。
对于“令人尴尬的并行”问题,当在c++上使用Intel TBB和OpenMP时,我观察到与用c#和TPL处理的类似(纯数学)问题相比,性能大约提高了10倍。SIMD是c#无法竞争的一个领域,但我也有一个印象,TPL有相当大的开销。
也就是说,我只在性能关键的任务中使用c++,我知道我将能够多线程并快速得到结果。对于其他任何事情,c#(偶尔f#)都很好。
我发现2020年4月读过:https://www.quora.com/Why-is-C-so-slow-compared-to-Python,作者是一位拥有15年以上软件开发经验的现实世界的程序员。
它指出,c#通常较慢,因为它被编译为公共中间语言(CIL),而不是像c++那样的机器代码。然后,CIL通过公共语言运行库(CLR)输出机器代码。但是,如果您继续执行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++中你必须…呃,自己做出所有这些选择(甚至更多),理想情况下,这样你的解决方案才能最好地解决你正在处理的问题。
问问自己是否真的想要或需要该控件,因为即使对于上面的简单示例,您也可以看到尽管性能有了显著的改进,但它需要更深入的投资才能访问。
I suppose there are applications written in C# running fast, as well as there are more C++ written apps running fast (well C++ just older... and take UNIX too...) - the question indeed is - what is that thing, users and developers are complaining about ... Well, IMHO, in case of C# we have very comfort UI, very nice hierarchy of libraries, and whole interface system of CLI. In case of C++ we have templates, ATL, COM, MFC and whole shebang of alreadyc written and running code like OpenGL, DirectX and so on... Developers complains of indeterminably risen GC calls in case of C# (means program runs fast, and in one second - bang! it's stuck). To write code in C# very simple and fast (not to forget that also increase chance of errors. In case of C++, developers complains of memory leaks, - means crushes, calls between DLLs, as well as of "DLL hell" - problem with support and replacement libraries by newer ones... I think more skill you'll have in the programming language, the more quality (and speed) will characterize your software.