现在java的执行速度和c++相比谁快?你怎么看?

忆往惜浮云


绝大多数情况下,都是C++比JAVA快。前者直接编译成本地机器语言,后者需要虚拟机即时编译。前者没有垃圾回收,后者有垃圾回收。前者可以栈上分配资源,后者依赖编译器和虚拟机(不确定性)。

但是也需要清楚,在某些时候,JAVA速度更快。这是建立在C++还没有精通或者不想花时间优化的前提下。JAVA的虚拟机有时非常智能,它可以自动对代码进行优化。而C++编译器则优化空间较少,它的哲学是把更多的优化机会留给程序员。

JAVA虚拟机常见的自动优化有以下这些。自动把某些资源放到栈上分配,自动把某些函数设置为内联。还有更厉害的,内存池。采用内存池时(预先分配一大块),内存分配会有一定提速,也防止了内存碎片。还有缓存技术,把一些可能经常用的对象预先分配,以后每次new的时候直接用现成的。也就是表面上看是new了个对象,实际上并没有发生分配内存的动作,而是直接使用全局的一个可以反复重用的对象指针。还有“写时修改”策略。即克隆一个大对象时,并没有真正克隆(仅仅是复制一个指针),而是直到发现新对象变更时才真正克隆。

这些优化,用C++通通都可以做,而且还可以手动做,不依赖编译器自动优化(JAVA通常依赖自动优化,不能手动)。C++要做的就是该栈上分配的就栈上分配,该内联的就内联(内联不了的直接少调用函数,或写成宏)。顺便说一下,JAVA似乎都没有栈上分配(除了基本类型)和内联的概念,因为是靠虚拟机自动智能实现的。更加复杂的就是内存池了,自己实现一个内存池。另外还有多用缓存,不要什么东西都从堆上新分配。

但是现实情况是,多数C++程序员都没有这些优化能力,或者即使有也没有那个时间折腾,赶工期嘛。还有一点很重要,性能优化后的代码往往可读性都很差,而且代码变复杂!这就导致了,在某些时候,类似的代码,JAVA速度反而更快。

最后,还需要强调,上面说的JAVA有时候比C++快,这种情况并不多见。有也是经常发生在C++初学者身上。而且只要是C++代码经过高度的优化,基本上是一定比高度优化的JAVA要快的!

我们可以把C++比喻成有强大功能(光圈,变焦,曝光时间等)的相机,而JAVA是高度智能的一键式傻瓜式相机。当一个不会手动调参的摄影师用专业相机时,并不一定比一键式傻瓜相机自动调参拍出来的效果好。而一个专业摄影师,则一定拍出来比傻瓜式相机效果好。


犍为真人


理论上一样快,有时候cpp快,有时候java快。

注意,我说的可不是“Java一定比C++快”这种公认荒谬的神论,如果你不知道什么叫“有时”,那么请直接离开这个回答,因为你没资格继续看。

我估计有人肯定听了就不乐意了,什么?java一定比cpp慢才对,因为java是用虚拟机运行,虚拟机是c/cpp写的,所以可以得出java一定比cpp慢!

然而不是,因为java不是脚本语言。再次重申,java不是脚本语言!而上面提到的思维明显是把java当成脚本语言对待了。虚拟机本质上仍然是提供虚拟硬件,有一套自己的处理器指令集,不然你以为还要编译一遍是为了保密?另一个证明是,java真的能直接运行在硬件上(有虚拟机,那就一定能造出真机嘛),注意,是真的是直接运行在硬件上而不是什么用硬件集成一套其他语言编写的运行环境再运行。以前有过这种芯片,可惜推出之后没什么市场,最终也就消失在历史中了。不过这已经能证明java是基于硬件指令操作而不是基于什么其他高级语言翻译再操作的根本性质了。

有本事你给js或是其他什么脚本语言也造个真机出来?

正是因为这一特性,导致了java可以比c++更快。举个最容易理解的例子,c++创建一个对象需要4走个真正的cpu指令,而java只需要走1个虚拟机cpu指令。那么,1个虚拟机cpu指令需要用4个真正的cpu指令运行么,显然不需要。

如果看到这,你还是不相信java可以比cpp快的,甚至还想在下面留言用各种已经解释了可你还是理解不了的想法来反驳,那这里直接给你做一个随手就能来一个的例子。下面,就分别用cpp和java创建一百万个功能完全相同的对象,来测试执行耗时。

测试环境是MacBook pro2016款,jdk1.8.0-131,g++为4.2.1系统自带,clang为10.0.1(更适合编译未经优化的代码),那么结果如何呢?

首先登场的是c++,测试代码如下。可以看出都是最基本的操作,哪怕是初学者都能轻松看懂:

那么运行的结果如何呢?见下图。再次提醒,这里使用clang实际上已经在给c++加buff了!


接下来,该java登场了。还是同样的环境,测试代码如下,可以说基本就是c++代码的翻版。控制台里已经显示了第一次的运行结果,当然,为了公平起见,我们同样多测试几次……

这是第二次结果:

这是第三次结果:







现在,你还觉得c++一定比java快么?事实胜于雄辩,除非你是靠嘴编程的选手。


青阳桦榎


纯粹的对比速度,没有多大意义的。如果纯论速度,越底层语言速度一定是越好的(离机器越近,速度就越快)。理想情况,二进制是最快的,再汇编,再C,再C++。语言越高级,中间的转换损失就越大。理想情况下,能用二进制写好程序绝对是最快的。但是,语言越底层,就越难控制,对编写人的能力要求就急剧增加,程序越难写的好。完成一件任务,不好的程序对速度等这些将会产生巨大影响。这还不提编程的速度问题,后期的维护问题这些影响。

因此,评估速度的快慢问题放置到要解决的问题下来考虑可能更有意义。若性能有比较极致的要求,在可行的情况下,选择更低级的语言会有更大的优化空间。这也是操作系统层面需要采用更底层语言的原因。

现代互联网应用快速发展的情况下,非极致要求下,大部分任务对时间的要求比对极致速度的要求要重要的多(非极力优化的情况下,速度相差感知不那么强)。越高级的语言越容易快速的解决问题,这也是这几年像kolin这些jvm语言会快速发展的原因。

效率更重要!


原语9102


先划一下重点:本问题是纯粹比较运行速度!

看了一下这些回答,有些人可能因为自己是做java的,见不得自己做的东西差,死都不承认java速度慢。为什么java比cpp慢?大家都说得差不多了我不想再啰嗦。我只想从其他方面反过来证明。

首先,java程序员是中国所有程序员里最多的!说句不好听的话,如果java的运行效率等于或者高于cpp,那么早就不存在cpp这门语言了,因为没有理由用它!cpp的缺点大家都知道,编写效率低(注意是编写效率,不是运行效率!这两者成反比!);复杂难理解;掌握这门语言需要先掌握操作系统;等等。

其次,现在那些追求高性能(也就是高运行效率)的服务器上面跑的程序是用什么语言写的?是c和cpp,没有java写的高性能服务器!java或者c#或者python或者php写的服务器那是玩玩的,你家oa或者erp或者其他mis可以用这些语言写,但此类系统软件追求的正是编写效率高!追求性能的服务器指的是科学计算类、游戏服务端类等等。

第三,某楼层回答说java编写出来的程序最终跟汇编写的程序一样,都是生成了机器码运行。我想问问层主,你懂汇编吗?会使用汇编写代码吗?最终生成的机器码是一样的吗?!你确定java生成的机器码不包含有罗里吧嗦一大堆没用的东西,而只有极少的部分是用于做正确的事情?!

我举个例子,同样是上山,比如我用汇编写实现是一条天梯从山底直通山顶,而用java实现是山路十八弯。机器码在同一台电脑运行速度一样所以这里人走路的速度一样(注意,任何语言包括解释型语言,其最终都是依靠机器码才能运行。机器码的运行速度一样是说明硬件速度固定,而不是java运行速度跟汇编一样!),你说是我走天梯直通上方先到山顶,还是走山路十八弯盘上去快?答案显而易见吧?!我建议该楼主好好看看我的回答,多学习多理解,避免扯淡误导跟您一样无知的萌新!


小关云长


java就不要和cpp比了,设计思路不同。

至少能保证在大多数情况下,cpp会快。

原因就是cpp设计稍微底层一些,有些东西由用户裁剪。比如运行时类型信息,异常处理都是可以裁剪的,而且没有垃圾收集,自己选择合适的时机释放内存,当然应该还有其他jvm实现的功能在cpp上没有。

但是java建立在更上层的优势就是开发速度更快。语言的高级话更在于解决开发速度。并非解决性能问题。如果某块对性能有要求,项目自然会转到cpp,c,甚至汇编解决这些问题。


zhangyiant


从语言本身来说,当然还是c/c++性能好,但现在也分场景,看从哪个角度说。比如C/C++的机制本身就很快,一个函数调用只传指针,而Java需要传对象,这在复杂度高的程序里差别就很大了,但Java开发框架较多,这些年虚拟机也不断提升性能,因此有了很大提高。不客气的说句话,记得学车的时候有个老师傅说,没有肉车,只有肉人,每个人写的代码快慢也因人而异吧


叶枪枪


c++呀,这不明摆着吗


学长来也


1.1 Java VS C/C++

Java与C++相比的优点在于:

  • Java比C,C++简单,学起来比C\\C++容易

  • Java完全对象化,比如数组在Java中是一个对象,含有length这个属性;而不像C++中数组是一个指针。所以访问数组,Java都会进行边界检查,更安全,但牺牲了速度。同时因为Java中所有类都会继承Object基类,所以可以把几个好不相干的类用基类联系起来,比如放在同一个数组里。

  • Java中没有指针的概念。

  • Java中有完善的内存管理机制,能自动垃圾回收,最大可能降低内存溢出的可能,同时提高编程效率。

  • Java中有完善的异常机制(标准C++中不够完善)。

  • java中保持数据时对象本身是在堆里,同时靠一在栈里的句柄与之连接。这个设计更合理。

  • Java标准库完整的多,相比之下C++除了一个STL(而且还超级难用)就没了,实际C++编程中需要大量使用第3方库。这很大程度上是因为Java有一些商业公司支持,更新速度快,而C++只有一个可怜的标准委员会,上一个C++标准版本还是C++98。

  • Java因为是把程序编译为字节码,运行时需要JVM把字节码再翻译为机器码,所以他跨平台,一次编译到处运行。但这也是他慢的根本原因。

  • Java原生支持多线程(C++仅靠标准库办不到),原生的UI,如AWT Swing。

C++与Java相比的优点在于:

  • Java比C\\C++慢。Java 1.0 比C慢20倍 现在的Java 1.6运行速度也只是C的一半。

  • C++在继承和派生上比Java更灵活。

  • C++ 中可以直接插入汇编 能直接操控底层硬件 所以操作系统还是得用c写。

  • Java办的到C++一定办得到,C++办得到的Java则不一定。

  • Sun被甲骨文收购了之后,Java的发展很受影响。

  • C++编译的程序可以直接运行,Java需要安装JRE有几十MB,影响产品发布的用户体验。

1.2 常规思维:C/C++比Java快

常规认为:java运行速度比C++慢。

主要原因是:

  • java是解释性语言,java程序在运行时类加载器从类路经中加载相关的类,然后java虚拟机读取该类文件的字节,执行相应操作。而C++编译的时候将程序编译成本地机器码。一般来说java程序执行速度要比C++慢10-30倍。即使采用just-in-time compiling (读取类文件字节后,编译成本地机器码)技术,速度也要比C++慢好多。

  • java程序有要从网络上加载类字节,然后执行,这也是导致java运行速度慢的原因。

  • 在程序运行过程中,java虚拟机要检测数组是否越界,在C++中则不检测。

  • java中所有的对象都创建在堆中,没有对象被创建在stack中,而C++有的对象和变量是创建在stack中的

  • java在运行过程中检测对象的引用是否为空,如果引用指向都空指针,且执行某个方法时会抛出空指针异常

  • java运行时对类型检测,如果类型不正确会抛出ClassCastException异常。

  • java的垃圾回收机制较C++由程序员管理内存效率更低。

  • java中的原始数据类型在每个操作系统平台长度都是相同,而C++这些数据类型长度是随操作系统的不同而不同,所以java在不同操作系统上执行时有个转化过程。

  • 在java中String 是UNICODE.当java要操作一个 ASCII string 时,比C++效率上相对要低一些。

  • java中采用的是动态链接。

可以看出,这些比较,全部停留在理论的角度。那么实际应用如何呢?是骡子是马,需要拉出来溜溜嘛!

1.3 实际权威测试结果

http://nuclearjava.blogchina.com/642833.html

Java 比 C++ 快的理论依据

http://nuclearjava.blogchina.com/1792677.html

驳“.net比java快”的谎言

http://nuclearjava.blogchina.com/1902610.html

摘要

C++的速度是由C++编译器在程序员开发时编译出来的机器语言的优化程度决定的。

Java的速度是由Java的JIT和HotSpot编译器将java bytecode在运行时“即时”编译成针对本地CPU的优化的本地代码决定的。

比速度的实际就是在比:看C++编译器和java编译器谁能产生更优化的机器代码。

很明显,C++ 的编译器不如 java 的 JIT 和 HotSpot 编译器,因为 JIT 和 HotSpot 编译器能针对 CPU 指令集进行人优化、能在运行时根据使用频率对 method 进行内联和优化。而 C++ 的静态编译器永远也做不到这些。

据 IBM 研究院的数据显示,随着 java 技术的进步,java 在同样的硬件上的性能从1996年到2001年提高了10倍,而且还在不断提高。

SUN 的数据显示:j2se 1.5 在各种单项性能上平均比 j2se 1.4.2 高出 10% 到 30%,而在复杂程序的综合性能上则是 j2se1.4 的三倍左右。

在丹麦 Copenhagen 大学的一份长达 314 页的研究报告中,我们看到:

JDK 1.0时,java的速度是C++的20到40分之一。而到了jdk1.4时,java的性能则是C++的三分之一到2倍(通常C++是java的1.2倍到1.5倍)。在jdk 1.4.2时,java性能全面超过C++。

java在j2se 1.4.2时就已经在性能上全面超过了以c++,以下是几十个权威证据。

  1. 美国国家标准科技研究院 12项测试中,java获胜7项,C获胜5项。结论:大多数情况下,java更快;

  1. 苹果电脑公司的一份报告:在字符串比较上,Java的性能是C的6.4倍:

  1. 美国国家标准科技研究院的另一份报告证明:Java的全面战胜同时代的VC和Borland C;

  1. Java写的数据库的性能是C++写的数据库性能的近600倍!

  1. BGS Systems 公司的三位作者的共同研究报告:我们开始测试是否java程序能够接近C++的性能。但我们吃惊的发现:在client/server应用程序中,java性能优于MFC。

  1. 伯克利大学和Lawrence伯克利国家实验室的一份报告证明:IBM的JDK比GCC更快:

  1. 用纯java写的JDK底层要比用C++写JDK底层要快:

    JNode是一个纯java的操作系统,其jdk底层是用纯java写的。

  1. 美国国家标准研究院的一分报告:Java战胜MS VC++ Netbot 联合公司的证据:http://www.javaworld.com/javaworld/jw-02-1998/jw-02-jperf_p.html 中: java和C++在以下方面打成平手

Integer division

Dead code

Dead code with Integer division

Floating-point division

Static method

Member method

Virtual member method

但 java 在以下方面的速度是 C++ 的约 3 倍

Virtual member method with down cast and Run-Time Type Identification (RTTI)

http://www.kano.net/javabench/data

14 项 Benchmark 中,Java 获胜 9 项,C++5项 。

java 以 9:5 战胜 C++,而且其中很多项是以大比分领先:

Methord Call:近20倍

Object creation:4倍

Hash: 2倍半

word count:1倍半

Fibonacci:1倍半

http://cpp.student.utwente.nl/benchmark/

结果

14 个 Benchmark 中

Java-server SUN JDK1.4.2以6比8负于Inter C++8.0

Java-server SUN JDK1.4.2以8比6战胜GCC-i686

Java-server SUN JDK1.4.2以7比7战平GCC-i386

结论:基本战平

但是在此测试中,作者说他“故意”限制了JVM的内存使用量,说这是为了和 C++公平。这其实是很不公平的。

java 打开 -server 的目的就是为了“用空间换时间”,在内存中将 bytecode 编译成更大但是更快的本地码,作者却限制内存使用,就如同飞机与汽车比速度时给飞机和汽车同样数量的汽油一样,或者在限制飞机的飞行高度为5米以下一样(飞机在燃料不足或低空的情况下是不可能以最快的速度飞行了)。看似公平,实则极不公平,飞机就是靠大量的燃料来加速,不给燃料还比什么呢?如果给飞机和汽车同样多的燃料,飞机每跑100米就要停下来加一次油,怎么可能发挥最快速度呢?

而且,所有的java程序都会比相同算法的c++程序的内存用的多,毕竟JVM就要占去很多内存,如果想比较java和c++的速度,就绝不能要求他们的内存是相同的,就如同想比较飞机和汽车谁快,就绝不能要求他们用的油是相同的。

如果不限制内存使用量的话,相信 java 会更快。

Java code 比 C++ 更快的原因:C++进行的优化是静态优化,都是在编译的时候进行的。一旦编译链接生成的可执行本地代码,就盖棺定论了, 不能更改了,除非是 Hacker 或是病毒。就现在的编译技术来看,静态优化在总体上还是最成熟的,并且在编译的时候它没有时间压力,可以花很长时间来优化程序。

这点 Java 和 .NET 是不允许的。但是静态优化也有它的缺点,因为它不知道这些程序在运行的时候具体会有什么特征,无法针对性地进行优化。比如它就不可能“大胆”的进行 Method inlining。

因为它胆子大了就可能犯错误。比如一个Class A,它有个简单函数public int Foo() {return 3;},它的两个子类B和C Override了这个Foo()函数。那么在静态编译的时候,C++的编译器不能将Foo()这个函数作inlining优化,因为它不知道在运行的时候到底是A,还是B或是C的Foo()被调用。而Java的虚拟机在运行时就会知道这些信息。

如果发现运行的时候是B的Foo()在反复被调用,那么它就 大胆的将B的Foo()拿到调用者的程序里面来,这样的inlining处理避免了Function call的开销(仔细说就是No method call;No dynamic dispatch;Possible to constant-fold the value)。

对于简单的小函数,调用开销往往比执行还费时间。省略了这些开销性能会成倍的提高。如果这些小函数被上千上万次的调用,那么这样优化下来的效果就非常明显了。这也就是Java在有的时候比C++更快的原因之一。

当然,Java做优化实际上相当复杂,因为“大胆”优化有时候也会出现问题。比如 将B的Foo()的inlining了,结果突然的蹦出一个对A的Foo()的调用,那程序岂不是要出问题?这个时候呢,Java要退一步,进行反优化 (De-optimization),以确保程序的正确。就这样,Java的虚拟机“骑着毛驴看账本---走着瞧”。一边执行,一边优化,运行不停,优化不止。

从外表上看,Java的程序执行会不停的有小的波 动。我说的动态优化/反优化就是原因之一(还有很多其他原因)。

Java这种特性非常适合长时间运行的服务器端程序,因为这样Hotspot才有足够的机会对程序进行优化。如果程序只是简单的“Hello world”,那Hotspot一点忙帮不上。并且对于“Hello world”这么个简单的程序,一个Java VM也要启动,这就像你点着了一台锅炉,只是想煎一个鸡蛋。好多人觉得Java慢,最初的影像可能就是来源于此。

有人这时候一定会问:“既然这样,那为什么Hotspot不对程序就行全盘优化,那样岂不是更好?”。问题是这样的,优化是有代价的。比如一段程序运行要 2毫秒,优化要10毫秒。如果这段程序的执行密度很低,那么Hotspot就会觉得优化不划算而不予优化。你不妨这样想,Hotspot是一个精明的商人,赔本的生意它绝对不会做。

最后再指出一点,那就是 Hotspot 有客户机和服务器两套(-client, -server),它们有不同的优化方针和策略。


程序员杂货铺


我们把程序运行速度量化为0-10.

1年开发经验 Java 5 CPP 0

3年开发经验 Java 5 CPP 1

5年开发经验 Java 6 CPP 2

10年开发经验 Java 6 CPP 10

100年开发经验 Java 6 CPP 10

基本就是这个样子...

所以企业开发选择Java...


ACME63610374577


执行速度要看实际情况的,部分情况下java完全可以超过cpp。

很多人说java执行要靠jvm实时翻译成机器码,其实并不是每次都要翻译,对于经常调用的部分会翻译成机器码,后面直接调用,jvm并且会根据实际代码运行情况,借助于jit实时优化编译的机器码,比如好几行java代码会被翻译成很小一段高效的机器码,同一段代码执行速度会越来越快,这些是cpp做不到的,cpp一旦编译完成速度就固定了。

网上很多人做速度比较只是写个测试,跑一边就完事了,很多时候jvm的各种优势都没体现出来,根本不能代表实际应用的速度,服务器经常都是长年累月不停

web生态java完全吊打cpp,所以大型企业级应用这块java优势很明显,新兴的golang也不错


分享到:


相關文章: