我的理解是C / C ++产生本地代码在一个特定的机器体系结构上运行。 相反,就像在一个虚拟机的顶部Java和C#运行其抽象了本地建筑语言。 按道理它会为Java似乎是不可能的或者C#来匹配C的速度++,因为这中间步骤的,但是我已经告诉了最新的编译器(“热点”)可以达到这个速度甚至超过它。
也许这是一个多语言问题编译器的问题,但任何人都可以用简单的英语解释它是如何可能对这些虚拟机器语言来执行比母语更好的呢?
我的理解是C / C ++产生本地代码在一个特定的机器体系结构上运行。 相反,就像在一个虚拟机的顶部Java和C#运行其抽象了本地建筑语言。 按道理它会为Java似乎是不可能的或者C#来匹配C的速度++,因为这中间步骤的,但是我已经告诉了最新的编译器(“热点”)可以达到这个速度甚至超过它。
也许这是一个多语言问题编译器的问题,但任何人都可以用简单的英语解释它是如何可能对这些虚拟机器语言来执行比母语更好的呢?
一般情况下,C#和Java可以一样快或者更快,因为JIT编译器 - 它会编译您的IL在第一时间它执行的编译器 - 可以使一个C ++编译的程序不能因为它可以查询机最优化。 由此可以判断,如果机器是Intel或AMD; 奔腾4,单核或双核; 或者,如果支持SSE4等
A C ++程序必须使得它运行体面以及所有机器上,通常预先用混合优化编译,但是尽可能多的未优化,因为它可以用于单个配置(即处理器,指令集,其他硬件)。
另外某些语言特性允许在C#和Java编译器,使你的代码,允许其优化某些部位靠近,只是不是为C / C ++编译器进行安全的假设。 当您访问指针有很多的优化,仅仅是不安全的。
此外Java和C#可以更有效地做堆分配比C ++因为垃圾收集器和代码之间的抽象层允许它做所有的堆压缩一下子(相当昂贵的操作)。
现在,我不能对Java说话就这一个点,但我知道,C#,例如将实际删除的方法和方法调用时,它知道方法的主体是空的。 它会用这样的逻辑在你的代码。
因此,大家可以看到,有很多的原因,某些C#或Java实现会更快。
现在,这一切说,具体的优化可以在C ++中,将打击剥夺任何你可以用C#做的,尤其是在图形领域和任何时候你接近的硬件进行。 指针在这里创造奇迹。
所以,这取决于你在写什么,我会用一个或其他去。 但是,如果你正在写的东西是不依赖于硬件(驱动器,视频游戏等),我就不会担心的C#的性能(再不能谈论的Java)。 它会做就好了。
一个Java端, @Swati指出一篇好文章:
https://www.ibm.com/developerworks/library/j-jtp09275
正如在以前的帖子已经说了,JIT可以在运行时编译IL /字节码转换为本地代码。 那费用是mentionned,而不是它的结论:
JIT有一个大问题是,它不能编译:JIT编译需要时间,所以JIT编译将只代码的某些部分,而静态编译器会产生一个全面的本地二进制:对于某些类型的节目,静态编译器将完全可以轻松地胜过了JIT。
当然,C#(或Java,或VB)通常更快产生可行和可靠的解决方案比是C ++(如果仅仅是因为C ++有复杂的语义,和C ++标准库,而有趣和强大,是相当差时,与全比较从.NET或Java标准库的范围内),所以通常的C ++和.NET或Java JIT不会对大多数用户可见的,并为那些关键的二进制文件,好了,你可以还叫C ++处理差异从C#或Java(即使这种本地调用都可以在自己相当昂贵)...
注意用等值的C#或Java,通常,你比较C ++运行时代码。 不过C ++有一个特点,可以超越的Java / C#开箱,那就是模板metaprograming:码处理将在编译时进行(从而增加大大编译时间),导致成零(或几乎为零)运行。
我还没有那么看到这是一个现实生活中的作用(我只打了一些概念,但那时,差异执行对JIT的秒,对于C 零 ++),但是这是值得一提的是,旁边的事实模板metaprograming不不重要的...
希望
...
我还没有那么看到这是一个现实生活中的作用
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 ++开发工具包的一部分。 现在,写分配器是不容易的,然后,我们大多数人有更好的事情要做,而对于大多数的使用,RAII或GC是绰绰有余好了。
现在,内存模型在一定程度上成为多核和多线程技术的兴起更复杂。 在这方面,我想.NET的优点,和Java,有人告诉我,保持在上地面。 这很容易让一些“关于裸机”黑客称赞他的“机器附近的”代码。 但现在,它是相当更难手工不是让编译器的工作产生更好的装配。 对于C ++,编译成为通常比自十年黑客更好。 对于C#和Java,这是更容易。
尽管如此,新的标准的C ++ 0x将对一个简单的存储器模型,以C ++编译器,这将标准化(并因此简化)有效多处理/并行/线程代码在C ++中,并通过优化用于编译器更容易和安全。 但是,我们会在一些几年看看自己的诺言举行如此。
上周,我对.NET优化训练,发现静态编译器是非常重要的反正。 由于比JIT重要。
在C ++ / CLI(或其祖先,托管C ++)编译非常相同的代码可能是次比在C#中产生的相同的代码更快(或VB.NET,其编译器产生比C#相同的IL)。
因为C ++静态编译是好了很多,产生比C#的已经优化的代码。
例如,在.NET内联函数被限制为其字节码小于或大于在长度32个字节相等的功能。 因此,在C#中的一些代码会产生一个40个字节的访问,这将不被JIT是有史以来内联。 在C ++ / CLI相同的代码将产生一个20个字节的存取,这将是由JIT被内联。
另一个例子是临时变量,同时还在由C#编译器生成的IL被提到的是被简单地编译程C ++编译器。 C ++静态编译优化将导致更少的代码,因此批准了更激进的JIT优化,再次。
这样做的原因,推测是事实的C ++ / CLI编译器从广大的优化技术中获益,从C ++编译器的原生。
我爱C ++。
但据我所见,C#或Java是所有的一切更好的选择。 不是因为他们比C ++快,但因为当你加入了他们的素质,他们最终被更有效率,需要更少的培训,并具有较完整的标准库比C ++。 而对于大多数的节目,他们的速度差(以这种或那种方式)可以忽略不计...
我现在5个月几乎独家专业C#代码(这增加了我的简历已经完全的C ++和Java和C ++ / CLI的触摸)的。
我打的WinForms(咳咳......)和WCF(爽!),和WPF(酷!!!!双方通过XAML和原材料C#。WPF是很容易的,我相信摇摆只是无法比拟的话),以及C#4.0。
得出的结论是,虽然它更容易/更快地产生,在C#/ Java的比C ++工作的代码,这是一个很大很难产生在C#中强,安全可靠的代码(甚至难以在Java中)比C ++。 原因比比皆是,但它可以通过来概括:
readonly
和Java final
无处为C ++的有用const
( )。 因此,C#,只要你想要的东西的工作仍然是一个令人愉快的语言,但一个令人沮丧的语言,你想要的东西, 运作的瞬间。
Java是更令人沮丧的,因为它比C#一样的问题,以及更多:缺少的C#相当于using
关键字,我的一个非常熟练的同事用C花了太多的时间来确保其资源投入到正确的释放,而相当于++会是很容易(使用析构函数和智能指针)。
所以我想C#/ Java的生产率的提高是最明显的代码......直到有一天,你需要的代码要尽可能完美。 那一天,你就会知道痛苦。 (你不会相信什么从我们的服务器和GUI应用问...)。
我不停地跟服务器团队接触(我曾其中2年,才到GUI团队之前),在建筑物的另一边,我学到一些有趣的东西。
过去几年中,趋势是有Java服务器应用程序注定取代旧的C ++应用程序服务器,如Java有许多的框架/工具,并且易于维护,部署,等等等等。
......直到低延迟的问题饲养它丑恶的头的最后几个月。 然后,Java服务器应用程序,无论是试图通过我们的技术Java团队的优化,简单,干净地输掉了比赛反对旧,没有真正优化的C ++服务器。
目前,该决定是保持共同使用,其中的性能,同时仍然是重要的,不是由低延迟目标有关Java的服务器,并积极优化低延迟和超低延迟的需求已经快C ++服务器应用程序。
如预期没有什么是简单。
Java和更加C#,凉爽的语言,具有广泛的标准库和框架,在那里你可以编写快速,并很快产生。
但是,当你需要的原始动力,强大的和系统的优化,强大的编译器支持,强大的语言功能和绝对安全,Java和C#,很难以质取胜,你需要保持在竞争中的最后一个失踪,但关键的百分比。
这是因为如果你需要更少的时间和更少的经验的开发人员使用C#/ Java的比C ++产生的平均质量的代码,但在另一方面,你需要优秀的,以完美的品质代码的那一刻,它突然更容易和更快地获得结果右在C ++中。
当然,这是我自己的看法,也许仅限于我们的具体需求。
但是,它仍然是今天发生的事情,无论是在图形用户界面团队和服务器端的团队。
当然,如果新的东西发生了,我会更新这个帖子。
“我们发现,在关于性能,C ++以大比分胜出,但也需要最广泛的调整工作,其中许多是在复杂的程度就无法使用一般的程序员来完成。
[...] Java版本可能是容易实现的,而是要分析性能最难的。 特别是围绕垃圾回收的影响是复杂的,非常难调“。
资料来源:
“在Facebook上会话,就是‘ 合理编写C ++代码只是跑得快’,这凸显了在优化PHP和Java代码花费了巨大的精力。奇怪的是,C ++代码更困难比其他语言写的,但高效的代码是容易得多[在C ++写的比在其他语言中]“。
- 香草萨特在//建立/ ,报价安德烈Alexandrescu的
资料来源:
每当我谈管理与非托管的表现,我很喜欢指向系列波多黎各(和Raymond)也比较C ++和中国/英语词典的C#版本。 这谷歌搜索将让你看自己,但我喜欢波多黎各的总结。
所以,我是通过我的惨败丢人吗? 几乎不。 托管代码得到了很好的结果,对于几乎没有任何的努力。 为了击败雷蒙德管理必须:
- 写自己的文件I / O的东西
- 写自己的字符串类
- 写他自己的分配器
- 写自己的国际制图
当然,他可以用较低的水平库要做到这一点,但是这仍然是一个大量的工作。 你可以叫什么留下了STL程序? 我不这么认为,我认为他保留了性病:: vector类最终从来就不是一个问题,他不停的查找功能。 几乎一切都没了。
所以,是的,你肯定能击败CLR。 雷蒙德可以使他的计划去得更快,我认为。
30ms的每个 - 有趣的是,如通过程序内部定时器大约是相同报道的时间来解析文件。 所不同的是在头顶上。
对我来说,底线是,花了6次修订非托管版本击败托管版本,是原非托管代码的简单移植。 如果您需要的性能每一点(和必须得到它的时间和专业知识),你必须去非托管,但对我来说,我会处理的幅度利用顺序我对第一个版本在33 %I增益如果我尝试6次。
针对特定CPU优化的编译通常高估。 只要看看在C ++程序,并与优化编译Pentium Pro和在Pentium 4上运行,然后用优化的奔腾4,重新编译我经过漫长的下午有几个程序做。 一般的结果? 通常不到性能提升2-3%。 因此,理论JIT的优势几乎没有。 表现最分歧,只能采用标量数据处理功能,这东西最终需要手工精细tunning无论如何,以实现最大性能时,可以观察到。 这一类的优化是缓慢而昂贵的执行使他们有时不适合于JIT反正。
在现实世界和实际应用C ++依然是通常比Java快,主要是因为产生更好的高速缓存性能较轻的内存占用。
但使用所有的C ++功能您,开发人员必须努力工作。 您可以取得骄人的业绩,但你必须使用你的大脑了点。 C ++是决定用更多的工具,为您呈现,充电,你必须学习他们能够使用的语言以及价格的语言。
因为它优化了目标平台JIT(准时编译)可以非常快。
这意味着,它可以利用任何编译器的欺骗你的CPU可以支持,无论什么CPU开发商写的代码。
在.NET JIT的基本概念是这样的(大量简化):
调用首次方法:
调用用于第二时间的方法:
正如你所看到的,第二次左右,其几乎相同的过程,C ++,除了与实时优化的优势。
尽管如此,仍然有放慢托管语言其它开销问题,但JIT有很大帮助。
我喜欢猎户座阿德里安的答案,但有一个方面吧。
同样的问题提出了几十年前约汇编语言与像FORTRAN“人”的语言。 和部分答案是相似的。
是的,C ++程序能够被比C#快于任何给定的(非平凡?)的算法,但在C#程序常常是一样快或比C ++中的“幼稚”执行,和C中的优化版本更快++将需要更长的时间来开发,并且通过一个很小的幅度可能仍然击败了C#版本。 那么,是不是真的值得吗?
你必须回答一个接一个的基础上这个问题。
这就是说,我是C ++的很长一段时间的风扇,并且我认为这是一个令人难以置信的表现力和强大的语言 - 有时被低估。 但在许多“现实生活”的问题(就我个人而言,这意味着“我得到报酬的那种解决”),C#将会把工作更快,更安全的完成。
你付出最大的惩罚? 许多.NET和Java程序内存猪。 我已经看到.NET和Java应用程序需要的内存,百兆“数百名”当类似的复杂的C ++程序蜻蜓点水的MB的“十位”。
我不知道你会怎么经常会发现Java代码的运行速度比C ++,即使有热点快,但我会在解释它如何会发生采取摇摆。
想想编译Java代码解释机器语言的JVM。 当编译的代码的某些部分会热点处理器通知要使用多次时,其执行机器代码的优化。 由于手工调整大会几乎总是快于C ++编译的代码,这是确定的数字,编程,调整机器代码是不会太糟糕。
因此,对于高度重复的代码,我可以看到它会是可能的热点JVM比C ++更快地运行Java ...直到垃圾收集开始发挥作用。 :)
一般来说,你的程序的算法将是很大的应用程序不是语言的速度更重要。 你可以用任何语言实现一个贫穷的算法,包括C ++。 考虑到这一点,你通常可以在帮助你实现一个更高效的算法语言的运行速度更快编写代码。
高级语言的许多有效的预构建的数据结构和鼓励的做法,这将有助于你避免低效的代码提供更容易获得做的非常好,在这一点。 当然,他们可以在次也可以很容易地写了一堆很慢的代码也一样,所以你还是要知道你的平台。
此外,C ++与“新”赶上(注意引号)功能,如STL容器,自动指针,等等 - 见Boost库,例如。 你可能偶尔会发现,来完成一些任务,以最快的方式需要像,严禁在高级语言指针运算的技术 - 尽管他们typcially允许您根据需要调出的语言编写一个库,可以实现它。
最主要的是要知道你正在使用,它相关的API,它可以做什么语言,什么它的局限性。
我也不知道...我的Java程序总是慢。 :-)我从来没有真正发现C#程序是特别慢,但。
这里是另一个基准野趣,你可以尝试自己在自己的计算机上。
它比较ASM,VC ++,C#,Silverlight的,Java小程序,JavaScript中,闪存(AS3)
Roozz插件速度演示
请注意,JavaScript的速度varries很大,这取决于什么样的浏览器执行它。 因为这些插件在同一个进程中的托管浏览器中运行这同样适用于Flash和Silverlight真的。 但Roozz插件运行标准的.exe文件,它在自己的进程中运行,因此速度不是由托管浏览器的影响。
你应该定义“性能比好。”。 嗯,我知道,你问的速度,但它的计算并不代表一切。
依此类推,其偏颇,是的;)
随着C#和Java你付出你所得到的(更快的编码,自动内存管理,大库等)的价格。 但是,你有没有多少空间来讨价还价有关的细节:取完整的软件包或没有。
即使这些语言可以优化一些代码来执行比编译代码快,整个方法是(恕我直言)效率低下。 想象一下,每天开车5英里你的工作场所,与一辆卡车! 它的舒适,感觉很好,你是安全的(极端的溃缩区),你踩油门了一段时间后,它甚至会以最快的速度为标准的车! 我们为什么不都有卡车开车上班? ;)
在C ++中,你得到你所支付的,而不是更多,而不是更少。
引用Bjarne的Stroustrup的:“C ++是我最喜欢的垃圾回收的语言,因为它会产生这么少垃圾” 链接文本
从Java或C#编译器生成的可执行代码不会被解释 - 它被编译成“及时”本机代码(JIT)。 因此,在一个Java / C#程序在第一时间代码执行过程中遇到,有一些开销,因为“运行时编译器”(又名JIT编译器)打开字节代码(Java)的或IL代码(C#)插入本机机器指令。 然而,当应用程序仍在运行的代码遇到下一个时间,本地代码,立即执行。 这就解释了一些Java / C#程序如何似乎开始缓慢,但随后表现得更好,他们运行的时间越长。 一个很好的例子是一个ASP.Net网站。 在第一次的网站被访问,如C#代码是由JIT编译器编译为本地代码,可能会有点慢。 随后的访问导致更快的网站 - 服务器和客户端缓存一边。
在这里你问的具体问题,有一些很好的答案。 我想退一步看看更大的图片。
请记住,你的用户,你写的软件速度的感知受许多其他因素比代码生成多么好优化的影响。 这里有些例子:
手册内存管理是很难正确(无泄漏)做的,甚至难以effeciently做(你用它做不久后可用内存)。 使用GC是,在一般情况下,更容易产生管理内存以及程序。 你是否愿意非常努力地工作,并延迟交付软件,企图出做GC?
我的C#是容易阅读和理解比我的C ++。 我也有更多的途径来说服自己,我的C#代码工作正常。 这意味着我可以优化我的算法与引入错误的风险更小(和用户不喜欢崩溃,即使它很快做它的软件!)
我可以在C#快于C ++创建我的软件。 这腾出时间来工作表现,仍然按时交付我的软件。
它更容易编写C#比C ++好的UI,所以我更可能是能推的工作背景,同时UI保持响应,或提供进度或hearbeat UI当程序阻止了一会儿。 这并不做任何事情更快,但它使用户对等待幸福。
一切,我说一下C#可能是真实的Java,我只是没有经验,肯定地说。
如果你是一个Java / C#程序员学习C ++,你会被诱惑保持了Java / C#的角度思考和逐字翻译为C ++语法。 在这种情况下,你只能得到解释/ JIT本机代码与先前提到的好处。 为了获得在C最大的性能增益++与Java的/ C#,你必须学会思考在C ++和设计代码专门利用C ++的优势。
套用Edsger Dijkstra算法 :你的第一语言]地切割心收不回。
套用杰夫阿特伍德 :你可以写在任何新的语言[你的第一语言。
其中最显著JIT优化的方法是内联。 Java的甚至可以内联虚方法,如果它可以保证运行的正确性。 这种优化通常无法通过标准的静态编译器,因为它需要整个程序的分析,这是困难的,因为单独汇编(相比之下,JIT拥有所有可以利用的程序)来执行。 方法内联提高了其他优化,得到较大的代码块来优化。
用Java / C#标准的内存分配也比较快,和回收(GC)是不是要慢得多,但只有不足确定性。
虚拟机语言是不可能超越编译语言,但他们可以得到足够接近,这并不重要,(至少)由于下列原因(我说的Java在这里,因为我从来没有做过C#)。
1 / Java运行时环境通常是能够检测的代码块频繁运行,因此,在未来,他们在全编译运行速度执行这些板块的只是在实时(JIT)编译。
2 / Java库的广大部分被编译,这样,当你调用库函数,你执行编译的代码,而不是解释。 您可以通过下载OpenJDK的看到(C语言)的代码。
3 /除非你正在做大量的计算,多的程序正在运行,它等待输入从一个非常缓慢(相对而言)人的时间。
4 /由于大量Java字节码的验证中的加载的类的时间完成,运行时检查的正常开销大大降低。
5 /在最坏的情况下,性能密集代码可以被提取到一个编译模块和从Java(见JNI)调用,以便它以全速运行。
总之,Java字节码将永远不会超越本机语言,但有办法缓解这种。 爪哇(在我看来)的最大优势是巨大的标准库和跨平台性。
猎户座阿德里安 ,让我翻转你的文章,看看你的言论毫无根据的怎么是,因为很多可以关于C说++为好。 并告知的Java / C#编译器优化掉空函数没有真正让你听起来像你不是我的优化专家,因为一)为什么要一个真正的程序包含空功能,除了非常糟糕的遗留代码,B)是真的不黑色和前沿的优化。
除了这句话,你公然咆哮指点一下,但不要在Java和C#对象的基本工作原理类似C ++指针? 愿他们不重叠? 愿他们不能为null? C(和大多数C ++实现)具有限制关键字,两者都具有值的类型,C ++有参考对数值与非空保证。 什么是Java和C#的报价?
一般情况下,C和C ++可以一样快或更快,因为AOT编译器 - 即编译代码部署,之前曾经和所有,你的高内存许多核心构建服务器上的编译器 - 可以进行最佳化,一个C#编译的程序不能因为它有大量的时间这样做。 编译器可以判断该机采用Intel或AMD; 奔腾4,单核或双核; 或者支持SSE4等,如果你的编译器不支持运行时调度,您可以通过部署专门的二进制文件解决少数为自己。
C#程序时,使其运行体面以及所有机器上运行它通常编译,但是尽可能多的没有经过优化,因为它可能是一个单一的配置(即处理器,指令集,其他硬件),它必须花一些时间第一。 功能,如循环裂变,环反转,自动矢量化,整个程序优化,模板扩张,IPO,更多的人,都很难得到解决一切,完全不打扰最终用户的一种方式。
另外某些语言特性允许在C ++编译器或C,使你的代码,允许其优化某些部位靠近,只是不为Java / C#编译器进行安全的假设。 当你没有获得仿制药的全部类型ID或保证程序流程还有很多的优化,仅仅是不安全的。
还C ++和C做许多堆栈分配一次只用一个寄存器递增,这肯定是比Java类和C#的分配作为用于垃圾收集器和代码之间的抽象层更有效。
现在,我不能对Java说话就这一个点,但我知道,C ++比如编译器会实际删除的方法和方法调用时,它知道方法的主体是空的,它会消除常见的子表达式,它可能会尝试和重试找到最优的寄存器使用,它不执行边界检查,它将autovectorize环和内环和将反转内至外,它移动条件句移出循环,它分裂和unsplits环路。 它将扩大的std ::载体导入原生零个开销数组作为你会做的C方式。 它会做内部程序optimmizations。 它会直接在主叫网站建设的返回值。 这将折叠和传播表达式。 这将重新排序的数据到缓存友好的方式。 它会做跳转线程。 它可以让你写的编译时间射线示踪剂与零运行时开销。 这将使基于非常昂贵的图形优化。 它会做强度降低,是它取代某些代码与语法完全不平等的,但在语义上等效代码(旧的“异或富,富”只是最简单的,但这类过时的优化)。 如果你恳请它,你可以省略IEEE浮点标准,能够更加优化,例如浮点操作数重新排序。 它按摩,并屠杀了你的代码后,它可能会重复整个过程,因为通常情况下,某些优化奠定甚至certainer优化奠定了基础。 它也可能只是洗牌参数重试,看看如何在其内部排名的其他变种的分数。 它会用这样的逻辑在你的代码。
因此,大家可以看到,有很多的原因,某些C ++或C语言实现会更快。
现在,这一切说,许多优化可以在C ++做会吹走任何东西,你可以用C#做的,尤其是在数字运算,实时性和贴近金属的境界,但不排除存在。 你甚至不必接触一个指针很长的路要走。
所以,这取决于你在写什么,我会用一个或其他去。 但是,如果你正在写的东西是不依赖于硬件(驱动器,视频游戏等),我就不会担心的C#的性能(再不能谈论的Java)。 它会做就好了。
一般情况下,某些广义的论点听起来在具体岗位很酷,但一般不健全肯定可信。
不管怎么说,讲和:AOT是伟大的,因为是JIT。 唯一正确的答案可能是:这要看情况。 而真正聪明的人都知道,你可以使用两全其美的反正。
如果Java解释器生产,实际上是比机器代码的编译器生成你正在写的C ++代码的优化,到所在的C ++代码比Java和解释成本慢点的机器代码,它只会发生。
然而,实际发生的几率是相当低的 - 除非或许Java有一个非常精心编写的库,和你有自己写得不好的C ++库。
事实上,C#不真正在虚拟机中运行像Java一样。 IL被编译成汇编语言,其是完全的本机代码和以相同的速度作为本机代码运行。 您可以预先JIT的.NET应用程序,它完全消除了JIT成本,那么你就完全运行本地代码。
与.NET的放缓会不会因为.NET代码是比较慢的,但因为它的背后更多的是很多像垃圾回收做的事情,检查引用,存储完整的堆栈帧等,这可以说是相当强大的,有益的,当构建应用程序,而且是有代价的。 需要注意的是,你可以做所有这些事情在C ++程序,以及(多核心.NET功能其实就是.NET代码,你可以在转子查看)。 但是,如果你的手写相同的功能,你可能会用低得多的节目结束了,因为.NET运行时进行了优化和微调。
也就是说,托管代码的优势之一是,它可以完全可验证的,即。 你可以验证代码将永远不会访问另一个进程的内存,或者在执行之前做unsage的事情。 微软已经令人惊讶表明,100%的托管环境其实可以通过采取此验证的优势表现比任何现代操作系统显著更快地关闭由管理程序不再需要的安全功能完全托管的操作系统的研究原型(我们在某些情况下,说话像10X)。 SE电台有一个伟大的插曲说起这个项目。
在某些情况下,托管代码实际上可以不是本机代码更快 。 例如,“标记 - 扫描”垃圾收集算法允许像JRE或CLR环境中释放大量短暂的(通常)在单次通过,其中大多数C / C ++堆对象被释放的对象的一个烧录一时间。
从维基百科 :
对于许多实际的目的,在被垃圾收集语言实现分配/解除分配密集型算法实际上比使用手动堆分配它们的等同物更快。 这方面的一个主要的原因是,垃圾收集器允许运行时系统中的潜在有利的方式分期偿还的分配和释放操作。
这就是说,我已经写了大量的C#和大量的C ++的,我已经跑了很多基准。 根据我的经验,C ++是比C#快了很多,有两种方式:(1)如果你把你已经用C#编写一些代码,它移植到C ++的本机代码往往会更快。 如何更快? 那么,它改变了一大堆,但它不是经常看到一个100%的速度提升。 (2)在某些情况下,垃圾收集可以大规模放慢托管应用程序。 在.NET CLR不会有大的堆(比如,> 2GB),一个可怕的工作,并能最终花了很多时间在GC - 即使在有几个应用程序 - 甚至没有 - 对象的中间寿命期限。
当然,我已经中遇到大多数情况下,托管语言是速度不够快,由一个长镜头,以及C ++的额外性能维护和编码代价是根本就不是一个好。
这里有一个有趣的基准http://zi.fi/shootout/
其实Sun的HotSpot JVM使用“混合模式”执行。 它解释该方法的字节码,直到确定(通常通过某种类型的计数器),该代码(方法,循环,try-catch块等)的特定块将要被执行的很多,则JIT编译它。 需要的JIT编译时间的方法往往需要比如果该方法是,如果它是一个很少运行方法来解释更长的时间。 性能通常为“混合模式”更高,因为JVM不会浪费时间JIT编译的代码很少,如果有的话,运行。 C#和.NET不这样做。 .NET JIT们这一切,很多时候,浪费时间。
去了解惠普实验室迪纳摩 ,对于PA-8000的解释,关于PA-8000上运行,并经常运行程序的速度比他们做的本身。 然后,它会不会显得不足为奇!
不要把它想成一个“中间步骤” - 运行的程序包括很多其他的步骤已经在任何语言。
它常常可以归结为:
节目有热点,所以即使你正在运行速度较慢,你必须运行的代码体的95%,你仍然可以,如果你在炎热的5%的速度是性能竞争
一个HLL更了解你的意图不是像C / C一LLL ++,因此能产生更优化的代码(OCaml有更多的,并在实践中往往甚至更快)
JIT编译器有很多的信息是静态编译没有(如,实际的数据,你正好有这一次)
JIT编译器可以做到在运行时优化,传统的接头是不是真的允许这样做(例如重新排列分支所以常见的情况是平的,或内联库调用)
总而言之,C / C ++是相当糟糕的语言性能:有关于你的数据类型的资料比较少,没有有关数据信息,并没有动态运行时允许在运行时优化的方式很多。
你可能会得到短脉冲,当Java或CLR比C ++快,但整体表现是应用程序的生活变得更糟糕:看到www.codeproject.com/KB/dotnet/RuntimePerformance.aspx一些结果了点。
下面是悬崖点击答案: http://www.azulsystems.com/blog/cliff/2009-09-06-java-vs-c-performanceagain
我的理解是C / C ++产生本地代码在一个特定的机器体系结构上运行。 相反,就像在一个虚拟机的顶部Java和C#运行其抽象了本地建筑语言。 按道理它会为Java似乎是不可能的或者C#来匹配C的速度++,因为这中间步骤的,但是我已经告诉了最新的编译器(“热点”)可以达到这个速度甚至超过它。
这是不合逻辑的。 使用中间表示的不固有地降低性能。 例如,LLVM-GCC编译C和C ++通过LLVM IR(这是一个虚拟无限寄存器机),以本机代码,并能实现优异的性能(往往跳动GCC)。
也许这是一个多语言问题编译器的问题,但任何人都可以用简单的英语解释它是如何可能对这些虚拟机器语言来执行比母语更好的呢?
这里有些例子:
与JIT编译虚拟机便于运行时代码生成(如System.Reflection.Emit
上.NET),所以你可以编译生成的代码如C#和F#语言上的飞,但必须采取书面形式以比较慢的解释C或C ++。 例如,为了实现正则表达式。
虚拟机(例如,写屏障和分配器)的部件通常写在手工编码的汇编程序,因为C和C ++不生成足够快的代码。 如果方案强调系统的这些部分则可以想见,胜过任何可以用C或C ++编写。
本机代码的动态链接需要符合的ABI可能妨碍性能,避免了整个程序的优化,而链接通常是推迟了对虚拟机,可以从整个程序优化中受益(如.NET的物化仿制药)。
我也想解决以上paercebal的高度upvoted回答一些问题(因为有人不断删除我对他的回答评论)呈现反高效偏光观点:
码处理将在编译时做...
因此模板元编程只能如果节目是可用在编译时这是通常不是这种情况,例如,它是不可能写在香草℃的竞争性高性能正则表达式库++,因为它是不能运行时代码生成(的一个重要方面的元编程)。
......与类型打在编译的时候后...在Java中等同或C#是痛苦的最好写,而且将永远是较慢,即使类型在编译时已知的运行时解决。
在C#,也就是只有真正的引用类型的和不为值类型真。
无论JIT优化,什么都不会走了最快的速度直接指针访问内存...如果你有在内存中连续的数据,访问它通过C ++指针(即C指针...让我们给凯撒其应有的)将变为倍的速度比的Java / C#。
人们观察到的Java从SciMark2基准的SOR测试击败C ++正是因为指针阻碍走样相关的优化。
另外值得一提的是,.NET做链接,而C ++后键入整个动态链接库仿制药的专业化不能因为模板必须连接之前解决。 明明大优势仿制药有超过模板是可以理解的错误消息。
在什么一些其他人所说的顶部,从我的理解.NET和Java是在内存分配好。 例如,因为它得到碎片,而C ++不能(本身,但它可以,如果您使用的是聪明的垃圾收集器),他们可以压缩内存。
对于任何需要大量的速度时,JVM只是调用一个C ++实现,所以这是一个问题,他们更多的库有多好,比JVM有多好,对于大多数OS相关的东西。 垃圾收集削减你的记忆了一半,但使用一些发烧友STL和升压功能将有同样的效果,但有很多次错误的潜力。
如果你只是使用C ++库和大量的高层次的特点与许多类的大型项目,你可能会风比使用JVM慢。 除了更容易出错。
然而,C ++的好处是,它可以优化自己,否则你被卡住的编译器/ JVM做什么。 如果你把你自己的容器,写自己的内存管理多数民众赞成对齐,使用SIMD,并下降到装配在这里和那里,你可以加速至少2倍,4倍倍比大多数C ++编译器会自己做。 对于某些操作,16X,32X。 这是使用相同的算法,如果使用更好的算法和并行化,可以增加非常显着,有时几千倍的速度是常用的方法。
我看它从几个不同点。
一个非常简单的答案:给定一个固定的预算,你会取得比C ++应用程序性能更好的Java应用程序(ROI考虑)另外Java平台也更体面的剖析,这将帮助你更快地找准你的热点