C#真的比说C ++慢吗?


76

我一直在想这个问题已有一段时间了。

当然,C#中有些事情并未针对速度进行优化,因此使用这些对象或语言调整(如LinQ)可能会导致代码变慢。

但是,如果您不使用这些调整中的任何一项,而只是比较C#和C ++中的相同代码(将一个代码转换为另一个代码很容易)。真的会慢很多吗?

我看到的比较表明,在某些情况下C#可能甚至更快,因为从理论上讲,JIT编译器应实时优化代码并获得更好的结果:

托管还是非托管?

我们应该记住,JIT编译器是实时编译代码的,但这是1倍的开销,同一代码(一旦到达并编译)就不需要在运行时再次编译。

除非您创建并销毁了数千个对象(例如使用String而不是StringBuilder),否则GC也不会增加很多开销。而且在C ++中这样做也很昂贵。

我想提出的另一点是.Net中引入的DLL之间的更好的通信。.Net平台的通信要比基于托管COM的DLL更好。

我看不出为什么语言应该变慢的任何内在原因,而且我真的不认为C#比C ++慢(无论是经验还是缺乏很好的解释)。

那么,用C#编写的相同代码的一部分会比用C ++编写的相同代码慢吗?
如果是这样,那为什么呢?

其他一些参考资料(稍加讨论,但没有解释WHY):

如果C#比C ++慢,为什么还要使用C#?


因为C#比C ++更易于使用,尤其是在涉及GUI的情况下
Armen Tsirunyan 2011年

3
真的...要看...有些事情更快,有些则慢。C / C ++更具“确定性”(没有垃圾收集器在您身后)。如果您想产生100个线程,我可以告诉您GC会因为他的缓慢而困扰您(并且在告诉我100个线程太多之前,请知道Skype和McAfee AV现在在我的PC上分别有40个线程)。 ..在C#中封送处理很麻烦(而且速度较慢)。编码非常快。不,这不是火焰。我真的更喜欢C#。
xanatos 2011年

1
我认为应该对此进行编辑并重新打开。我认为提问者可能不会理解,一个更根本的问题会影响C#与C或C ++之类的语言之间的性能差异,即“由C编译器生成的代码(以及如何执行)与由C编译器生成的代码之间有什么区别? C#编译器?” C#/ Java和其他解释型或VM语言在运行其字节码时可能会具有几个中间步骤,而这些步骤在等效的C程序中是完全不存在的。
乔纳森·浮士德

3
尽管您可能认为(如上所述)这被视为“不是一个真正的问题”,但声称它是主观的却是荒谬的。“ A比B快”是可以客观衡量的。即使通过这种测量获得的答案是模棱两可的(有些事情更快,有些则更快),这仍然是客观的。
杰里·科芬

1
有关在许多不同类型的问题上对多种语言的全面比较,请参阅计算机语言基准测试游戏
阿萨夫·拉维

Answers:


143

警告:您提出的问题确实非常复杂-可能比您意识到的要复杂得多。结果,这是一个长的答案。

从纯粹的理论观点来看,可能对此有一个简单的答案:(可能)C#并没有真正阻止其像C ++一样快的速度。尽管有理论,但是有一些实际的原因,即在某些情况下某些情况下它的运行速度较慢。

我将考虑差异的三个基本方面:语言功能,虚拟机执行和垃圾回收。后两者经常一起使用,但是可以是独立的,因此我将分别对其进行研究。

语言特征

C ++非常重视模板,并且模板系统中的功能主要旨在在编译时尽可能多地完成功能,因此从程序的角度来看,它们是“静态的”。模板元编程允许在编译时执行完全任意的计算(即,模板系统已完成Turing)。这样,基本上任何不依赖用户输入的内容都可以在编译时进行计算,因此在运行时它只是一个常数。但是,对此的输入可能包括类型信息之类的内容,因此,您通常会在编译时通过C ++中的模板元编程在C#的运行时通过反射来完成很多工作。不过,在运行时速度和多功能性之间绝对需要权衡取舍-模板可以做什么,

语言功能上的差异意味着几乎所有通过将某些C#转换为C ++来进行两种语言比较的尝试(反之亦然)很可能会在无意义和误导性之间产生结果(对于大多数其他语言对也是如此)以及)。一个简单的事实是,对于任何大于几行代码的东西,几乎没有人可能会以相同的方式(或足够接近的相同方式)使用这些语言,这样的比较可以告诉您有关这些语言的信息在现实生活中工作。

虚拟机

与几乎任何合理的现代VM一样,Microsoft的.NET可以也将进行JIT(又称“动态”)编译。但是,这代表了许多权衡。

首先,优化代码(像大多数其他优化问题一样)在很大程度上是NP完全问题。对于除了真正的琐碎/玩具程序以外的任何事情,您几乎都可以保证不会真正地“优化”结果(即,您找不到真正的最优值)-优化器只会使代码比它更好以前是。但是,许多众所周知的优化都需要花费大量时间(通常是内存)来执行。使用JIT编译器时,用户正在等待编译器运行。排除了大多数较昂贵的优化技术。静态编译具有两个优点:首先,如果它很慢(例如,构建大型系统),通常是在服务器上执行的,而没有人花时间等待。其次,可执行文件只能生成一次,并被许多人使用多次。首先是将优化成本降至最低;第二种方法则是在大量执行中分摊出较小的成本。

如原始问题(和许多其他网站)所述,JIT编译确实有可能提高对目标环境的了解,这应该(至少在理论上)抵消了这一优势。毫无疑问,该因素可以抵消至少部分静态编译的缺点。对于一些相当特定类型的代码和目标环境,它可以甚至超过了静态编译的优势,有时甚至是巨大的优势。至少从我的测试和经验来看,这是非常不寻常的。取决于目标的优化通常似乎只产生很小的差异,或者只能(无论如何自动地)应用于相当具体的问题类型。显然,如果您在现代计算机上运行相对较旧的程序,就会发生这种情况。用C ++编写的旧程序可能已被编译为32位代码,并且即使在现代64位处理器上也将继续使用32位代码。用C#编写的程序将被编译为字节码,然后VM将其编译为64位机器码。如果该程序从以64位代码运行中获得了实质性的好处,那将带来巨大的好处。在64位处理器相当新的短时间内,这种情况发生了很多。不过,通常有可能会受益于64位处理器的最新代码通常可以静态编译为64位代码。

使用虚拟机还可以改善缓存使用率。VM的指令通常比本机指令更紧凑。在给定数量的缓存中可以容纳更多的代码,因此您有更大的机会在需要时将任何给定的代码放入缓存。这可以帮助使解释后的VM代码执行(就速度而言)比大多数人最初期望的更具竞争力-您可以在一个高速缓存未命中的时间内在现代CPU上执行许多指令。

还值得一提的是,这两个因素之间不一定完全不同。没有什么可以阻止(例如)C ++编译器产生旨在在虚拟机上运行(带有或不带有JIT)的输出的。实际上,Microsoft的C ++ / CLI几乎可以满足要求-一个(几乎)符合标准的C ++编译器(尽管有很多扩展),可以生成旨在在虚拟机上运行的输出。

反之亦然:Microsoft现在拥有.NET Native,它将C#(或VB.NET)代码编译为本地可执行文件。这样提供的性能通常更像C ++,但是保留了C#/ VB的功能(例如,编译为本机代码的C#仍支持反射)。如果您有性能密集的C#代码,这可能会有所帮助。

垃圾收集

从我所看到的,我想说垃圾回收是这三个因素中最难理解的。仅举一个显而易见的例子,这里的问题提到:“除非您创建并销毁了数千个对象,否则GC也不会增加很多开销。” 实际上,如果您创建销毁了数千个对象,则垃圾回收的开销通常将非常低。.NET使用分代清除器,它是各种复制收集器。垃圾收集器的工作原理是从指针/参考“地点”(例如,寄存器和执行堆栈)开始公知的易于访问。然后,它“追逐”那些指向已在堆上分配的对象的指针。它检查这些对象是否有进一步的指针/引用,直到将所有对象都跟随到任何链的末端,并找到(至少潜在地)可访问的所有对象。在下一步中,它将使用(或至少可能正在使用)所有对象,并通过将所有对象复制到堆中要管理的内存一端的连续块中来压缩堆。然后剩下的内存是空闲的(必须运行模数终结器,但至少在编写良好的代码中,它们很少见,因此我暂时将其忽略)。

这意味着如果创建和销毁大量对象,则垃圾回收只会增加很少的开销。由垃圾回收周期所花费的时间几乎完全依赖于已创建的,但对象的数量被破坏。匆忙创建和销毁对象的主要结果是,GC必须更频繁地运行,但是每个周期仍然会很快。如果创建对象但不销毁它们,GC将运行更频繁,并且每个周期将大大降低,因为它将花费更多的时间来追踪指向可能存在的对象的指针,花费更多的时间来复制仍在使用的对象。

为了解决这个问题,世代清除工作的前提是,已经“存活”了很长时间的对象很可能会继续存活更长的时间。基于此,它有一个系统,可以使在一定数量的垃圾回收周期中保留下来的对象得到“保留”,并且垃圾回收器开始简单地假设它们仍在使用中,因此,与其在每个周期进行复制,不如将其保留下来。他们一个人。这通常是一个有效的假设,以致世代清除通常比大多数其他形式的GC的开销要低得多。

人们对“手动”内存管理的了解也很少。仅举一个例子,许多比较尝试都假定所有手动内存管理也都遵循一种特定的模型(例如,最佳匹配分配)。与许多人关于垃圾收集的信念(例如,普遍认为通常使用引用计数完成)相比,这通常离现实更近(如果有的话)。

考虑到垃圾回收手动内存管理的策略多种多样,就整体速度而言,很难将两者进行比较。试图比较分配和/或释放内存的速度(本身)几乎可以保证产生的结果充其量是没有意义的,而在最坏的情况下则完全是误导性的。

奖励主题:基准

由于相当多的博客,网站,杂志文章等声称可以在一个方向或另一个方向上提供“客观”证据,因此我也会在这个问题上投入2美分的价值。

这些基准中的大多数都有点像青少年决定比赛自己的赛车,而无论谁获胜都可以保留两辆赛车。但是,网站在一个关键方面有所不同:发布基准的人可以同时驾驶两辆车。偶然地,他的车总是赢了,其他人都不得不满足于“相信我,我真的在尽你所能地开车。”

编写糟糕的基准测试很容易,它产生的结果几乎没有意义。几乎任何人都具备设计基准的必要技能,该基准可以产生有意义的结果,并且也具有产生可以给出他想要的结果的基准的技能。实际上,编写代码以产生特定的结果可能比真正产生有意义的结果的代码容易

正如我的朋友詹姆士·坎泽(James Kanze)所说,“永远不要相信基准并不会伪造自己。”

结论

没有简单的答案。我可以肯定地说,我可以掷硬币来选择获胜者,然后选择(说)1到20之间的数字作为获胜的百分比,并编写一些看起来像一个合理且公平的基准的代码,并且得出了已定的结论(至少在某些目标处理器上-不同的处理器可能会稍微改变百分比)。

正如其他人指出的那样,对于大多数代码而言,速度几乎是无关紧要的。推论到(这是更经常被忽略)是在小代码中速度非常重要,它通常是相当重要的很多。至少根据我的经验,对于真正重要的代码,C ++几乎总是赢家。肯定有一些有利于C#的因素,但是在实践中,它们似乎比那些有利于C ++的因素所抵消。您当然可以找到表明您选择结果的基准,但是当您编写真实代码时,几乎总是可以在C ++中使其比在C#中更快。可能会(或可能不会)花费更多的技巧和/或精力来编写,但是几乎总是可能的。


6
在以前的公司中,我们的一些决策是基于基准测试,但是基准测试做得不好,因为它错过了更大的前景(例如,对GC的影响)或做得不好。提防基准测试...倾向于根据上下文无关的内容来做出决策。如果您进行基准测试,请尝试使其尽可能具有代表性:)
Mark Simpson

4
IIRC,.NET运行时从不解释而是始终JIT。优化由编译器在编译时(源代码到IL)和运行时抖动(IL到本机指令)完成。如果某个方法花费太长时间来抖动,抖动可能会选择不优化。如果需要完全优化,则可以在安装时使用NGen生成本机映像。
Dudu

2
我认为答案实际上很简单:我的答案是:“是的,因为C#实际上迫使您使数据结构成为引用类型,这在包装的每一层中都增加了新的间接层,从而增加了内存流量并减少了内存局部性。在C ++中,无论您围绕一个对象包装多少层包装,该对象都将保留在内存中的同一位置。” 你同意吗?
user541686 2013年

2
@Mehrdad:是的,不是。从实际的角度来看,是的,这很可能经常会偏向于支持C ++。同时,GC在许多情况下都可以轻松地传递引用,从而避免复制数据。
杰里·科芬

2
@Mehrdad:是的,这就是我在想我所说的话:“在C ++中,您几乎总是可以比在C#中更快。它可能会(或可能不会)花费更多的技巧和/或精力来编写,但实际上几乎总是可能的。”
杰里·科芬

41

因为您并不总是需要使用(并且我经常使用)“最快”语言?我不会因为速度更快而开车去法拉利工作...


17
我认为这个比喻很贴切。如果我开车去上法拉利,我将无​​法更快地工作。汽车的行驶能力肯定比我驾驶的汽车快,但是汽车的性能并不是限制因素。有速度限制,交通,路况等。类似地,软件通常受用户交互,I / O等约束,在这种情况下,您使用哪种语言不会有太大区别。
Fred Larson

3
好吧,但问题是“哪辆汽车是法拉利,哪辆是大众汽车?” 还是两者都不是法拉利。
pepr

@pepr标题中的问题是,是的,但是帖子结尾的问题是“为什么可以在使用法拉利时使用大众汽车?”。
亚当·霍兹沃思

@AdamHouldsworth:是的。答案可能是相似的-“成本问题”。
pepr

不,我骑摩托车上班主要是因为它速度更快。
CashCow

20

大约在2005年,来自本机/托管隔离区两侧的两名MS性能专家试图回答相同的问题。他们的方法和过程仍然引人入胜,并且结论至今仍然有效-我不知道有什么更好的尝试来给出明智的答案。他们指出,关于绩效差异的潜在原因的讨论是假设性的和徒劳的,真正的讨论必须为此类差异在现实世界中的影响提供一些经验基础

因此,旧的新雷蒙德·陈Raymond Chen)和里科·马里亚尼Rico Mariani)制定了一场友好比赛的规则。选择了中文/英文词典作为玩具应用程序上下文:足够简单,可以被编码为业余爱好项目,但是足够复杂,可以演示非平凡的数据使用模式。规则从简单开始-Raymond编码了一个简单的C ++实现,Rico逐行将其迁移到C#,没有任何复杂性,并且两个实现都运行了基准。之后,随后进行了多次优化迭代。

的全部细节在这里:1234567891011121314

关于泰坦的对话非常有教育意义,我全心全意地建议您参加。但是,如果您缺乏时间或耐心,杰夫·阿特伍德(Jeff Atwood)整理的底线很漂亮

在此处输入图片说明

最终,C ++的速度提高了2倍-但最初,它的速度降低了13倍。

正如Rico总结的那样

那么,我为自己惨败而感到羞愧吗?几乎不。几乎无需付出任何努力,托管代码就取得了很好的结果。为了击败托管版本,Raymond必须:

  • 写他自己的文件/ IO的东西

  • 编写自己的字符串类

  • 编写自己的分配器

  • 撰写自己的国际地图

当然,他使用可用的低级库来执行此操作,但这仍然是很多工作。你能称呼剩下的STL程序吗?我不这么认为。

那仍然是我11年的经验,谁知道以后有多少C#/ C ++版本。

当然,这并不是巧合,因为这两种语言惊人地实现了它们截然不同的设计目标。C#希望在开发成本是主要考虑因素的情况下使用(仍然是大多数软件),而C ++却可以在您不节省任何费用的情况下将机器的每一刻性能发挥到极致:游戏,算法交易,数据-中心等


1
这是最好的答案,他总结得很漂亮!
Rodney P. Barbati

19

C ++始终在性能方面具有优势。使用C#,我不必处理内存,而我实际上有大量资源可用于完成工作。

您需要问自己的更多是关于哪一项可以节省您的时间。机器现在功能异常强大,您的大多数代码应以一种使您能够在最短时间内获得最大价值的语言来完成。

如果在C#中有一个核心处理花费太长时间,则可以构建一个C ++并与C#互操作。

不要再考虑代码性能了。开始创造价值。


12
+1表示“停止思考您的代码性能。开始
Thomas Matthews

2
我同意C#的开发速度。在许多情况下,它的价值更大。
Yochai Timmer

在每种情况下,开发人员都需要一个不错的选择。在某些情况下,C#无法满足需求。假定基于计算的应用程序,例如视频转换器或视频混合器或3D虚拟化或流量计算或游戏。您还必须注意项目目标硬件。某些应用程序必须在低端硬件上运行。
SMMousavi '16

6

C#比C ++更快。写得更快。对于执行时间,没有什么比分析器更好。

但是C#没有足够的库,因为C ++可以轻松地进行接口。

C#严重依赖Windows ...


5
C#需要来自编译器,操作系统和平台的更多支持。对嵌入式系统的巨大关注。
Thomas Matthews

C#的运行不仅仅是Windows,但苹果机,Linux,Android,iOS设备......看到microsoft.com/net/multiple-platform-supportxamarin.com/platformmono-project.com/docs/about-mono/支持的平台
yoyo 2015年

@yoyo:C#确实可以在其他平台上运行(Linux上也有Mono),但是您可能想使用的库(例如Windows窗体)可能没有。可移植性是C#开发的问题。
Alexandre C.

这个答案现在已经改变。Microsoft目前正式支持.NET Standard运行时在Linux上运行。因此,除非您必须在微控制器上进行开发,否则可移植性根本不是问题。更不用说它也变得更快了。
MovGP0

3

顺便说一句,时间紧迫的应用程序未使用C#或Java进行编码,这主要是由于不确定何时执行垃圾回收。

在现代,应用程序或执行速度没有以前那么重要。开发进度,正确性和稳健性是更高的优先级。高速版本的应用程序如果有很多错误,崩溃很多或更糟,错过了推向市场或进行部署的机会,那就不好了。

由于开发计划是当务之急,因此出现了新的语言以加快开发速度。C#是其中之一。C#还通过从C ++中删除会导致常见问题的功能来帮助确保正确性和鲁棒性:一个例子是指针。

在大多数平台上,使用C#开发的应用程序和使用C ++开发的应用程序在执行速度上的差异可以忽略不计。这是由于执行瓶颈与语言无关,而是通常取决于操作系统或I / O。例如,如果C ++在5毫秒内执行一个功能,但C#使用2毫秒,并且等待数据需要2秒钟,则与等待数据的时间相比,花费在该功能上的时间可忽略不计。

选择最适合开发人员,平台和项目的语言。努力实现正确性,健壮性和部署目标。应用程序的速度应视为错误:将其优先级确定,与其他错误进行比较并根据需要进行修复。


我的理解是C#(Java还是Java)不会“删除”指针的存在/概念,而是通过实际语法通过某种抽象将它们对程序员隐藏。不过,这是无关紧要的。C#的相对简单性是无可争议的。
Mike G

3

观察它的更好方法是,所有内容都比C / C ++慢,因为它是抽象的,而不是遵循粘泥糊的范例。之所以称其为系统编程,是因为您要对晶粒或裸金属进行编程。这样做还可以提高您使用其他语言(例如C#或Java)无法实现的速度。但是可惜的是,C语言的根源在于用困难的方式做事,因此您通常将编写更多的代码并花费更多的时间调试它。

C也是区分大小写的,C ++中的对象也遵循严格的规则集。例如,紫色冰淇淋蛋筒可能与蓝色冰淇淋蛋筒不同,尽管它们可能是蛋筒,它们不一定属于蛋筒家族,并且如果您忘记定义要出的蛋筒。因此,冰淇淋的性质可能是克隆,也可能不是。现在速度参数,C / C ++使用堆栈和堆方法,这是裸机获取金属的地方。

借助Boost库,不幸的是,大多数游戏工作室都坚持使用标准库来达到惊人的速度。另一个原因可能是因为用C / C ++编写的软件往往文件很大,因为它是一个庞大的文件集合,而不是一个文件。还请注意,所有操作系统都是用C编写的,因此一般来说为什么我们要问一个问题:什么可能更快?

缓存也没有比纯内存管理快,抱歉,但这不会散开。内存是物理的东西,缓存是软件的工作,目的是提高性能。也可能会导致没有物理内存缓存的情况将根本不存在。无论是自动还是手动,都不能使事实存储器必须进行某种程度的管理。


1

如果有更快的路由(C#),为什么还要编写一个不需要太多C ++优化方式的小型应用程序?


为什么?因为我很想知道我的代码何时运行。包括析构函数。即使是很小的应用程序,也都可以通过针对可读性进行优化而受益。
IInspectable '16

1

除非您在特定系统上执行基准测试,否则实际上不可能获得确切答案。但是,考虑诸如C#和C ++之类的编程语言之间的一些根本差异仍然很有趣。

汇编

执行C#代码需要执行JIT处理代码的附加步骤。关于性能,将有利于C ++。同样,JIT编译器只能在JIT(例如方法)的代码单元内优化生成的代码,而C ++编译器可以使用更具攻击性的技术跨方法调用进行优化。

但是,JIT编译器能够优化生成的机器代码,使其与基础硬件紧密匹配,从而使其能够利用附加的硬件功能(如果存在)。据我所知,.NET JIT编译器不会这样做,但是可以想象它能够为Atom生成与奔腾CPU相对的不同代码。

记忆体存取

在许多情况下,垃圾回收体系结构可以创建比标准C ++代码更多的最佳内存访问模式。如果用于第一代的内存区域足够小,则可以保留在CPU缓存内,从而提高性能。如果创建并销毁许多小对象,则托管堆的维护开销可能会比C ++运行时所需的开销小。同样,这在很大程度上取决于应用程序。一项有关性能的Python研究表明,由于更优化的内存访问模式,特定的托管Python应用程序的扩展能力比编译后的版本好得多。


JIT编译代码还有一个额外的步骤,但是由于重复使用的规则,您可能会比单次编译多使用该代码段10000倍。(例如:循环)。因此,存在一个问题,即JIT是否能很好地完成初始编译的压缩工作。
Yochai Timmer

0

不要混淆!

  • 如果最好的情况下编写C#应用程序,而最好的情况下编写C ++应用程序,则C ++会更快。
    这是为什么C ++固有地比C#更快的原因,例如C#使用类似于Java中JVM的虚拟机。基本上,高级语言的性能较低(如果在最佳情况下使用)。

  • 如果您是经验丰富的专业C#程序员,就像您是经验丰富的专业C ++程序员一样,那么使用C#开发应用程序比使用C ++更加容易和快捷。

这些情况之间的许多其他情况也是可能的。例如,您可以编写一个C#应用程序和一个C ++应用程序,以便C#应用程序比C ++应用程序运行得更快。

选择语言时,应注意项目及其主题的情况。对于一般业务项目,应使用C#。对于像视频转换器或图像处理这样的高性能项目,您应该选择C ++。

更新:

好。让我们比较一些实际原因,说明为什么C ++的大多数可能速度都超过C#。考虑一个好的书面C#应用程序和相同的C ++版本:

  • C#使用VM作为执行应用程序的中间层。它有开销。
  • AFAIK CLR无法优化目标计算机中的所有C#代码。可以最优化地在目标计算机上编译C ++应用程序。
  • 在C#中,对运行时的最大可能优化意味着最大可能的快速VM。VM仍然有开销。
  • C#是一种高级语言,因此它为最终过程生成更多的程序代码行。(考虑一下Assembly应用程序和Ruby应用程序之间的区别!相同的条件是C ++和高级语言(例如C#/ Java)之间)

如果您想以专家的身份在实践中获得更多信息,请参阅this。它是关于Java的,但也适用于C#。


0

主要关注的不是速度,而是跨Windows版本和升级的稳定性。Win32几乎不受Windows版本的影响,因此非常稳定。

当服务器退役并迁移软件时,使用.Net的任何事物都会产生很多焦虑,通常对.net版本会产生很多恐慌,但是10年前构建的Win32应用程序却一直运行,没有任何反应。


-1

我从事优化工作已有15年之久,并定期重新编写C ++代码,并尽可能多地使用编译器内在函数,因为C ++性能通常远不及CPU所能提供的。经常需要考虑缓存性能。替换标准C ++浮点代码需要许多向量数学指令。大量的STL代码被重写,并且通常可以快许多倍地运行。随着CPU接近其最佳性能,大量使用数据的数学和代码可以用惊人的结果重写。

这在C#中是不可能的。比较它们的相对“实时”性能确实是一个令人惊讶的无知问题。C ++中最快的代码段将是每条汇编程序指令针对现有任务进行优化时,根本没有多余的指令-根本没有。在需要时使用每个内存,而不是复制n次,因为这是语言设计所需要的。每个所需的内存移动都与高速缓存协调工作。在无法改进最终算法的情况下,根据准确的实时要求,同时考虑准确性和功能性。

然后,您将寻求最佳解决方案。

将C#与这种理想情况进行比较是惊人的。C#无法竞争。实际上,我目前正在编写一堆C#代码(当我说重写时,是指完全删除并替换它),因为它甚至不在同一座城市,更不用说在繁重的实时性方面了性能。

所以,请不要自欺欺人。C#很慢。死得慢。所有软件的速度都在降低,而C#使这种速度下降变得更糟。所有软件都使用汇编器中的访存执行周期运行(您知道–在CPU上)。您使用10倍的指令;它的速度将慢10倍。您削弱了缓存;它会变得更慢。您将垃圾回收添加到实时软件中,然后您常常被愚弄为代码运行“正常”,每时每刻只有几分钟,然后当代码“变慢了一段时间”。

尝试将垃圾收集系统添加到每个周期都很重要的代码中。我不知道股市交易软件是否具有垃圾收集功能(您知道吗,在运行在耗资3亿美元的新型海底电缆上的系统上)。我们可以每2秒节省300毫秒吗?航天飞机上的飞行控制软件又如何– GC可以吗?高性能车辆的发动机管理软件怎么样?(一个赛季的胜利可能价值数百万美元)。

实时垃圾收集是完全失败的。

因此,强调的是,C ++的速度要快得多。C#是向后飞跃。


1
C#并非向后飞跃,因为C#的设计要求与C ++完全不同。C#将执行速度换成开发速度。您指出C#会失败的所有这些示例(航天飞机,引擎管理等)都不是C#的目标应用程序。C#允许相对快速地交付完成的产品。C#允许产品在其虚拟机运行的任何硬件上运行。知道您的代码需要在一百种不同的硬件配置上运行时,您可以编写汇编优化吗?
mag_zbc

我同意您所说的mag_zbc,但最初的问题是“ C#真的比说C ++慢吗?” 我的“向后跳”评论是指C#的速度,而不是它的可移植性。
大卫·劳埃德

这是一个有偏见的观点,它基于纯粹的投机假设,没有提供任何基准。
zmechanic
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.