JIT与静态编译器
如前所述,JIT可以在运行时将IL/字节码编译成本机代码。报告提到了这方面的成本,但没有得出结论:
JIT有一个巨大的问题:它不能编译所有的东西:JIT编译需要时间,所以JIT只会编译代码的某些部分,而静态编译器将生成一个完整的本机二进制:对于某些类型的程序,静态编译器只会轻松地超过JIT。
当然,C#(或Java,或VB)通常比C+更快地产生可行和健壮的解决方案(如果仅仅因为C+具有复杂的语义,而C+标准库虽然有趣且功能强大,但与.NET或Java的标准库的全部范围相比,它很差),所以通常,C+与.NET或JavaJIT之间的区别对大多数用户来说是不可见的,对于那些至关重要的二进制文件,好吧,您仍然可以从C#或Java调用C+处理(即使这种本地调用本身成本很高).
C+元编程
请注意,通常,您将C+运行时代码与其在C#或Java中的等效代码进行比较。但是C+有一个可以优于Java/C#的特性,那就是模板元编程:代码处理将在编译时完成(从而大大增加编译时间),从而导致运行时为零(或几乎为零)。
我还看到了现实生活对此的影响(我只玩了一些概念,但到那时,JIT的执行时间是几秒了,而且零(对于C+),但是值得一提的是,除了模板元编程之外,.
编辑2011-06-10:在C+中,处理类型是在编译时完成的,这意味着生成调用非泛型代码的泛型代码(例如,从字符串到T类型的泛型解析器,为它识别的类型调用标准库API,并使解析器易于被其用户扩展)是非常容易和非常有效的,而Java或C#中的等价物编写起来最好是痛苦的,而且即使在编译时知道类型时,也总是比较慢和解析。希望就是让JIT把整件事都做好。
...
编辑2011-09-20:闪电战+(首页, 维基百科),显然,他们的目标是通过C+模板元编程,尽可能从运行时执行转移到编译时间,从而达到FORTRAN在科学计算方面的性能。所以“我还没有看到现实生活对这件事的影响。“显然,我上面写的部分是吗?存在于现实生活中。
本机C+内存使用
C+的内存使用量不同于Java/C#,因此具有不同的优点/缺陷。
无论进行JIT优化,没有什么比直接访问内存的指针更快了(让我们暂时忽略处理器缓存等等)。因此,如果内存中有连续的数据,可以通过C+指针(即C指针.让我们给凯撒应得的回报吧)将会比Java/C#快一倍。C+有Raii,这使得处理过程比C#甚至Java容易得多。C+不需要using
以确定其对象的存在范围。而C+没有finally
条款。这不是错误。
:-)
尽管C#原语类结构,C+“在堆栈上”对象在分配和销毁时不会花费任何费用,并且不需要GC在一个独立的线程中进行清理。
至于内存碎片,2008年的内存分配器不是1980年以来的旧内存分配器,它们通常与GC:C+分配相比不能在内存中移动,是这样的,但是,就像在Linux文件系统上那样:当碎片不发生时,谁需要硬盘碎片整理呢?为正确的任务使用正确的分配器应该是C+Developer工具包的一部分。现在,编写分配器并不容易,然后,我们大多数人都有更好的事情要做,而且对于大多数使用来说,Raii或GC已经足够好了。
编辑2011-10-04:有关高效分配程序的示例:在Windows平台上,因为Vista,低碎裂堆默认情况下启用。对于以前的版本,可以通过调用winapi函数来激活lfh。堆信息)。在其他操作系统上,还提供了可供选择的分配器(请参阅https:/secure.wikimedia.org/Wikipedia/en/wiki/malloc清单)
现在,随着多核和多线程技术的兴起,内存模型变得更加复杂。在这个领域,我猜.NET有优势,而且我被告知Java占据了优势。对于一些“光秃秃的金属”黑客来说,赞美他的“接近机器”的代码是很容易的。但是现在,手工生成更好的程序集要比让编译器完成任务要困难得多。对于C+来说,自十年来编译器通常比黑客做得更好。对于C#和Java来说,这甚至更容易。
然而,新的标准C+0x将向C+编译器强加一个简单的内存模型,这将使C+中有效的多处理/并行/线程代码标准化(从而简化),并使编译器的优化更容易、更安全。但是,在几年后,我们将看到它的承诺是否属实。
C+/CLI与C#/VB.NET
注意:在本节中,我讨论的是C+/CLI,即.NET托管的C+,而不是本机C+。
上周,我接受了.NET优化方面的培训,发现静态编译器无论如何都是非常重要的。比JIT更重要。
在C+/CLI中编译的相同代码(或其祖先,托管C+)可能比C#(或VB.NET中的编译器生成的IL与C#相同)中生成的相同代码快一倍。
因为C+静态编译器比C#生成已经优化的代码要好得多。
例如,.NET中的函数内联仅限于字节长度小于或等于32个字节的函数。因此,C#中的一些代码将生成一个40字节访问器,JIT不会将其内联。C+/CLI中的相同代码将生成一个20字节访问器,它将由JIT内联。
另一个例子是临时变量,这些变量是由C+编译器编译掉的,而C#编译器生成的IL中仍然提到这些变量。C+静态编译优化将导致代码减少,因此再次授权进行更积极的JIT优化。
之所以出现这种情况,是因为C+/CLI编译器从C+本机编译器的大量优化技术中获益。
结语
我喜欢C+。
但据我所见,C#或Java都是更好的选择。这并不是因为它们比C+更快,而是因为当你把它们的质量加起来时,它们最终会变得更有效率,需要更少的培训,并且比C+拥有更完整的标准库。对于大多数程序来说,它们的速度差异(在某种程度上)是可以忽略不计的.
编辑(2011-06-06)
我在C#/.NET方面的经验
我现在几乎有5个月的专业C#编码(这意味着我的简历中已经满是C+和Java,还有一点C+/CLI)。
我和WinForms一起玩(嗯.)和WCF(酷!)和WPF(酷!通过XAML和原始C#。WPF是如此简单,我相信Swing无法与之相比),和C#4.0。
结论是,虽然生成在C#/Java中工作的代码比在C+中更容易/更快,但在C#中生成一个强大、安全和健壮的代码要比在C+中生成一个强大、安全和健壮的代码要困难得多。理由很多,但可以概括如下:
泛型不如模板强大。 (尝试编写一个有效的泛型分析方法(从String到T),或者在C#中编写一个有效的相等于Boost:词法_CAST的方法来理解这个问题。)
Raii仍然是无与伦比的 (GC仍然可以泄漏(是的,我必须处理这个问题),并且只处理内存。连C#using
并不是那么简单和强大,因为编写正确的Dispose实现是很困难的。)
C#readonly
和爪哇final
没有比C+更有用的了const
(在没有大量工作的情况下,您不可能在C#中公开只读的复杂数据(例如,节点树),而这是C+的内置特性。不可变数据是一个有趣的解决方案,但并不是所有的东西都是不可变的,所以到目前为止,它还不够).
所以,C#仍然是一种愉快的语言,只要你想要一些有用的东西,但在你想要的时候,它是一种令人沮丧的语言永远安全起作用了。
Java甚至更令人沮丧,因为它有着与C#相同的问题,还有更多的问题:缺少与C#相同的问题。using
关键字,我的一位非常熟练的同事花费了太多的时间来确保其资源被正确释放,而在C+中的等价物则很容易(使用析构函数和智能指针)。
所以我想C#/Java的效率提高对大多数代码来说是可见的.。直到有一天你需要代码尽可能的完美。那天你会知道痛苦的。(你不会相信我们的服务器和GUI应用程序要求什么)。
关于服务器端Java和C+
我和服务器团队保持联系(在回到GUI团队之前,我在他们中间工作了两年),在大楼的另一边,我学到了一些有趣的东西。
过去几年的趋势是,Java服务器应用程序注定要取代旧的C+服务器应用程序,因为Java有许多框架/工具,而且易于维护、部署等。
.直到低潜伏期的问题在过去的几个月里长出了丑陋的头.然后,Java服务器应用程序,无论我们熟练的Java团队试图进行的优化,简单而干净地输掉了与旧的,而不是真正优化的C+服务器的竞争。
目前,我们的决定是将Java服务器保留在性能仍然重要但不关心低延迟目标的通用服务器上,并积极优化已经更快的C+服务器应用程序,以满足低延迟和超低延迟的需求。
结语
没有什么比预期的简单。
Java和更多的C#是很酷的语言,拥有广泛的标准库和框架,您可以在那里快速编写代码,并且很快就会有结果。
但是,当您需要原始功能、强大和系统的优化、强大的编译器支持、强大的语言特性和绝对安全时,Java和C#使您很难赢得最后一个缺失但关键的质量百分比,您需要保持在竞争之上。
与C+相比,您需要更少的时间和更少经验的C#/Java开发人员来生成平均质量代码,但另一方面,当您需要优秀的代码来完善质量代码时,在C+中得到正确的结果突然变得更容易和更快了。
当然,这是我自己的看法,也许只限于我们的具体需要。
但是,这仍然是今天发生的事情,无论是GUI团队还是服务器端团队。
当然,如果有新的事情发生,我会更新这篇文章。
编辑
“我们发现,在性能方面,C+以很大的优势胜出,然而,它也需要最广泛的调优努力,其中许多是在一般程序员无法使用的复杂程度上完成的。
[.]Java版本可能是最简单的实现,但最难分析性能。具体来说,垃圾收集的影响很复杂,很难调整。“
资料来源:
编辑
“Facebook上最流行的说法是‘写得很好的C+代码运行得很快,这突出了在优化PHP和Java代码方面付出的巨大努力。矛盾的是,C+代码比其他语言更难编写,但是高效的代码(用C+编写比用其他语言编写)要容易得多。"
– 草本萨特在…/构建/引用亚历山大斯库
资料来源: