65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 与 C/C++ 性能对比

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.54/5 (25投票s)

2008 年 3 月 2 日

CC (ASA 2.5)

5分钟阅读

viewsIcon

200408

C++ 和 C# 性能比较。

引言

好吧,这是我在这个技术系列中的第一篇文章。事实上,这篇文章的标题迫使我开始了一个专注于技术的博客。说得很好,让我们现在进入正题。

关于以上主题,在不同的论坛、新闻组和其他各种帖子中已经有很多激烈的讨论。那么,为什么我还要在这里再次讨论呢?

好吧,尽管有很多讨论组声称 C++ 更快、更高效,但仍有一小部分人坚持认为 C# 更高效。
一个没有被编译成本地代码的语言怎么可能比 C++ 二进制文件更快呢?

尽管上述说法从 C++ 程序员的角度来看是完全有效的,但我还是想强调几点,说明为什么一些(并非全部)C# 程序确实比它们等效的 C++ 程序*更快*。

第一点:C# 被编译两次。一次是在编写程序时,第二次是在用户站点执行程序时。第一次编译由你的 C# 构建器完成,第二次由用户机器上的 .NET Framework 完成。C# 编译的应用程序可能更快的**原因**是,在第二次编译时,编译器知道实际的运行时环境和处理器类型,可以生成针对特定处理器的指令。经典的 C++ 编译器生成的本地代码通常是所有可用处理器的最低公分母,这意味着 C++ 程序将无法利用 Pentium 4 HT 处理器“超线程”指令集的优势。(当然,HT 现在已经过时了……)它也无法利用 Core 2 duo 或 Core 2 Quad 的“真正的多线程”指令集,因为编译器生成的本地代码甚至不知道这些指令集。
在早些年,每个处理器发布时,指令集的变化都不大。处理器的进步主要体现在速度上,每次发布只增加少量额外的指令集。Intel 或 AMD 通常期望游戏开发者使用这些额外的指令集。但随着 PIV 的出现,然后是 PIV HT、Core、Core 2、Core 2 Quad、Extreme,以及最新的 Penryn,每次发布都有额外的指令集可以被利用,如果你的应用程序需要高性能的话。有一些 C++ 编译器可以生成针对特定处理器的代码。但缺点是应用程序必须被标记为“此应用程序的最低系统要求至少是 Core 2 Quad 处理器”,这意味着很多客户会开始流失。
这正是 C# 的框架编译器发挥作用的地方。因为应用程序在用户站点进行了第二次编译,所以框架知道实际的运行平台,并且能够生成在该给定平台上运行最佳的代码。

第二点:那么,为什么*并非所有* C# 程序都运行得更快呢?

C# 或任何 .NET 应用程序都在一个沙盒环境中运行,因此许多指令都必须经过安全检查。因为额外的安全检查是有代价的,C# 会带来性能开销,这意味着像这样的程序:

for(int i=0;i<100000000;i++)
{
// pig 函数
Pig_Function();
}

其中 Pig_Function() 是一个非常耗时的操作,C++ 比它快一个数量级。我看到几乎所有声称 C++ 更快的帖子都会写一个这样的小应用程序来证明 C++ 至少比等效的 C++ 程序快 N 倍,是的,这是真的。微软不建议将 C# 用于对时间要求严格的应用程序。

第三点:那么,C# 何时才真正更快呢?
一个设计良好的 C# 程序的速度,可以达到一个等效的“设计良好”的 C++ 程序速度的 90% 以上。但关键在于“设计良好”的 C++ 程序。有多少人能在 C++ 应用程序中有效地管理内存,如果该应用程序非常庞大,比如有数百万行代码?“设计良好”一个 C++ 程序是极其困难的,尤其是在程序规模不断增大的时候。未能及时“释放”内存的问题在于,应用程序的工作集会增加,从而增加“页面错误”的数量。大家都知道页面错误是最耗时的操作之一,因为它需要访问硬盘。一次页面错误你就完蛋了。你花几个小时做的任何优化都会因为你没有“释放”不再需要的内存而在页面错误中被浪费掉。许多经典的应用程序,包括 Google Picasa,都存在内存管理问题。大约两三天后,你会发现这些应用程序运行速度变慢,需要重启 Windows。C# 完全解决了这个问题,框架会在执行过程中为你清理内存,因此你的工作集永远不会增大(除非你真的使用了它),这意味着页面错误更少。这意味着,“设计良好”一个 C++ 程序比等效的 C# 程序要复杂得多,而 C# 程序因其自身负责的性能问题而显得缓慢。

现在我仿佛听到了你在问我,
那么,总结一下,我应该怎么做?
这是个好问题。除了编写对时间要求严格的代码块之外,首选 C#。用 C++(不是 VC++ .NET)编写所有算法代码,将其编译成 dll,然后通过 C# 的 Dll Interop 调用它。这应该能平衡性能。这种技术并不新鲜,也不是我或任何人发明的。它类似于早期 C 语言与汇编语言的比较,一方面的人争论汇编语言更快,另一方面的人则说 C 语言更容易开发,然后人们开始使用汇编语言嵌入到 C 程序中,通过 asm 块来处理对时间要求严格的应用程序。

历史在重演……!

Mugunth

最初发布于我的博客

http://tech-mugunthkumar.blogspot.com/2008/02/c-vs-cc-performance.html

历史

这里没什么特别的。

© . All rights reserved.