为什么Java永远比C++慢?

为什么C语言 / C++ 永远不会被取代 数以百计的 C/ C++ 备选品出现了,但程序员仍将使用 C/ C++,因为重写面向 C/ C++ 的计算机历史是不现实的。这并不意味着 C 和 C++ 是好的语言——在某些方面 (例如复杂性、内存安全性等),备选语言可能比 C/ C++ 更好,但它们无法进入 C/ C++ 的领域,因为以前的程序员用 C 和 C++ 编写了整个现代计算机历史。在 20 世纪 20 年代,程序员实现了 C/ C++ 的备选品,如 Go、D、Rust 和 Carbon,它们具有 C/ C++ 从未提供的各种特性。 阅读详情

转载:https://blog.youkuaiyun.com/chrysanthemumcao/article/details/38495749

Why Java Will Always Be Slower than C++ 

by Dejan Jelovic 

为什么Java永远比C++慢? 

耍过Java程序,或者用Java码过程序的人都晓得,Java要比用C++写成的原生程序要慢。这是咱用Java时已经承认的事实。 
  不过,很多人想要说服我们说这只不过是暂时的,他们说Java从设计上来讲并不慢,相反,只是现在的JIT实现相对比较嫩,有很多能优化的地方JIT并没有优化到,拖了后腿。其实不然,不管JIT们多牛,Java永远要比C++慢。 
   
  我想说... 
  宣扬Java不慢于C++的人往往是觉得,(语法)严格的语言,可以让编译有更大的优化空间。因此,除非你想做人肉编译器优化整个程序,否则通常都是编译器做得更好。 
  这是真的。在数值计算领域,Fortran仍然胜于C++,的确因为它更严格。不用担心指针瞎搅和,编译器可以更安心地优化。C++想打败Fortran的唯一办法,就是好好设计一个像Blitz++那样的库。 

  测试... 
  Java可以跟得上C++的地方,就是基准测试。计算起第N个斐波纳契数,或者运行起Linpack,Java没理由不跟C++跑得一样快。当所有的计算都放在一个类里,并且只使用基本的数据类型,比如说int或者double时,Java编译器的确能跟得上C++的脚步。 

  事实... 
  当开始在程序中使用对象的时候,Java就放松了潜在的优化。这一节会告诉你为什么。 

  1. 所有的对象都是从堆里分配的。 
  Java从栈里分配的,就只有基本数据类型,如int,或者double,还有对象的引用。所有的对象都是从堆里分配的。 
  当有大量语义上是一回事的对象时,这不成问题。C++同样也是从堆上分配这些对象。但是,当有值语义不同的小对象时,这就是一个主要的性能杀手。 
  什么是小对象?对我来说,就是迭代器们。在设计中,我用了很多迭代器。别人可能会用复数。3D程序员可能会矢量或者点类。处理时间序列的人可能会有时间类。使用这些类的人,无一例外地讨厌把不费时间的栈上分配换成花费固定时间的堆上分配。假如把它放在一个循环里,就变成了O(n)对0了。如果再加一层循环,没错,又变成O(n^2)对0了。 

  2. 大量的转换。 
  得益于模板,好的C++程序员甚至可以写于完全没有转换的牛程序。不幸,Java没有模板,所以Java代码总是充满了转换。 
  对于性能,它们意味着什么?呃,在Java里所有的转换都是很费时的动态转换。多费时?想想你可能会怎么样实现转换的: 
  最快的方法就是,给每一个类赋值一个序号,然后用一个矩阵来描述任意两个类是否相关的。如果是的话,需要给指针加上多少的位移才能进行转换。这种方法的伪码看起来应该是这样的: 
DestinationClass makeCast (Object o, Class destinationClass) { 
Class sourceClass = o.getClass (); // JIT compile-time 
int sourceClassId = sourceClass.getId (); // JIT compile-time 

int destinationId = destinationClass.getId (); 

int offset = ourTable [sourceClassId][destinationClassId]; 

if (offset != ILLEGAL_OFFSET_VALUE) { 
return <object o adjusted for offset>; 
} 
else { 
throw new IllegalCastException (); 
} 
} 
好一堆代码。这只是一个简单的情景——用矩阵来表示类的关系浪费了一部分内存,没有哪个成熟的编译器会这样子做。他们会使用map或者遍历继承树,这样会变得更慢。 

  3. 攀升的内存占用。 
  Java程序储存数据占用的内存大概是相当的C++程序的两倍。原因如下: 
  1. 启用了垃圾收集的程序一般都比不使用垃圾收集的程序多花50%的内存。 
  2. 本来C++里在栈上分配的对象,到了Java就在堆上分配了。 
  3. Java对象比较大,因为所有的对象都有一个虚表,还要加上对(线程)同步的原生支持。 
大的内存映像让程序更大概率被放到磁盘的交换区去。没有什么比交换文件更慢的了。 
  4. 缺少更细致的控制。 
Java原来就是作为一种简单的语言来设计的。很多在C++里让程序员控制细节的特性在Java里都被一脚踢开了。 
  比如说,在C++里可以改进引用的位置(?)。或者一次申请和释放很多个对象。或者用指针耍一些小技巧,更快地访问成员。 
  5. 没有高层次的优化。 
  程序员处理高层次的概念。而编译器处理剩下的低层次概念。对于程序员来说,一个叫Matrix的类就代表了比一个叫Vector的类更高层次的概念。而对于编译器来说,这些名字都是符号表的一个入口。他们只关心类里面有哪些函数,函数里面有哪些语句。 
  这样想一下,比如说要实现一个exp(double x, double y)函数,计算出x的y次幂。对于一个编译器,它能只看一下这个函数,然后指出,exp(exp(x, 2), 0.5)可以优化成x自己吗?当然不行。 
  编译器能做的优化只是语句层面的,而y是在编译器里面的。即使程序员知道两个函数是对称的,可以把它们都消去,或者函数的调用顺序只是相反的,除非编译器能只瞄一下语句,然后指出来,不然优化是不可能完成的。 
  所以,如果想要完成一个高水平的优化,必须存在某种方法,可以让程序员来告诉编译器优化的规则。 

  没有哪个流行的程序语言/系统可以做到这点,至少已知的方法,比如微软承诺的智能语言,都不能。即便如此,在C++里可以用模板元编程来实现对高层次对象的优化。临时消除,部分求值,对称函数调用的消去,和其它可以用模板实现的优化。当然,不是所有的高层次优化都可以这样做。并且实现这些东西相当麻烦。但是大多数都可以完成,有人已经用这些技术实现了好些时髦的库。 

  不幸的是,Java没有任何元编程的特质,因此在Java中不会有这种高层次的优化。 
  所以... 

  由于存在这种语言特性,Java不可能达到C++这种速度。这相当程序上暗示了,对于要求高性能的软件和竞争激烈的COTS舞台上,使用Java不是一种明智的选择。但是因为它和缓的学习曲线,它的容错,和它庞大的标准库,所以适合开发中小型自用和定制软件。 

  附记... 
  1. 有人向James Gosling(谁?google之...)提交了很多可以改进Java性能的语言特性。文本在这里。不幸的是,Java语言已经有四年没有改动过了,所以看起来这些提议似乎不会在一夜之间被实现。 

  2. 最有可能往Java里加入泛型的是Generic Java。又很不幸的是,GJ只是通过在编译时把所有类型信息去掉来支持泛型。所以最后面执行环境看到的,仍然是缓慢的转换。 

  3. 垃圾收集的FAQ包含了关于垃圾收集慢于定制分配器的信息(上面第四点)。 

  4. 这里是一篇宣称垃圾收集比栈分配的快的文章。但是它的要求是物理内存必须是程序实际需要的内存的七倍之多。还有,它描述的是一种stop-and-copy(是不是那种执行到一半,然后停下来,把内存拷到另外一块内存,同时清除垃圾的那种方法?),而且还不是并发的。 

  反馈... 
  我收到很多关于这篇文章的反馈。附上一些典型的评论,还有我的回答: 

  “你还忘记了指出在Java里所有的方法都是虚方法,因为没有人会加上final关键字。” 
  事实上,不使用final关键字不是问题的关键所在,使用者才是。同时,虚函数也没有问题,但是却失去了优化机会。自从JIT们知道怎么样内联虚函数,这就变得不那么显著了。 

  JIT可以内联虚函数,所以Java可以比C++更快。 
  C++也可以使用JIT编译。不信的可以看看.NET的C++编译器。 

  到最后的时候,速度并不重要。电脑浪费了大部份时间在等待用户输入。 
  速度仍然很重要。我仍然在等我的笔记本启动起来,我在等我的编译器停下来,我还要等Word打开一个超长的文档。 
  我在一个金融公司工作。有时候我必须对一个很大的数据集进行模拟。速度在这种情况下都很重要。 

  有些JIT可以在栈上分配一些对象。 
  当然,一些。 

  你的转换代码看起来很丑。可以在类的继承层次上检查类。 
  首先,这样只比矩阵查找快一点点而已。 
  第二,这样只能查找类,类只占多少?低层次的细节往往是通过接口来实现的。 

  哈,那么我们都应该使用汇编? 
  不是的,我们都要使用对业务有用的语言。Java提供了庞大的标准库,让很多任务变得容易,因此Java是伟大的。它比其它所有的语言更容易移植(但并非100%可移植——不同的平台有不同问题)。它具有垃圾收集机制,简化了内存管理,同时也让某些构造如闭包可实现。 
  但是,同时,Java和所有的语言一样,也有瑕疵。在值语义的类型上缺少支持。它的同步并不是很有效率。它的标准库建立在异常检查之上,把实现拖进了接口。它的性能可以更好。它的数学库有些恼人的问题。诸如此类。 

  这些缺憾都是大问题吗?看你用它做什么。因此,在几种语言里,连同它的编译器以及可以选择的类库里选择对你的工程有利的一种。 

C和CPP的区别 & C++,Java and Python的区别 今天在论坛上看到两个学神讨论C++的优劣性引申出来的各种问题,深深感觉自己差距很大,现就部分问题做个小的总结。 C和CPP的区别: 1. C没有bool类型。布尔类型是int。0是假,非0是真。     2. C里字符常量(如'a'、'\n'、'\0'等)是int型,而C++里是char型。但这不影响使用。     3. 没有引用类型的变量,一般使用指针。函数的参数也不能是引用类型,想 阅读详情

相关推荐

3D识别建模 — 基于ReconstructMe和EAGLE EYES SCANNER的实现

3D实体识别建模,作为3D打印反向工程的一个重要环节,今天就让我们利用ReconstructMe和EAGLE EYES SCANNER来了解一下。 第一步、软件和硬件准备就绪 ReconstructMe下载并安装 http://reconstructme.net/?wpdmdl=160 EAGLE EYES SCANNER直接将相应USB插入电脑接口即OK,之后在    中点击搜索“设备管理...

qq_40013290的博客 881

为什么Java会比C++慢

最近在复习一些Java的基础知识,突然回想起了这个远古问题,就是基本上所有的人都在说Java比C++的运行速度慢很多很多,而这些人可能有绝大部分人也并不是很清楚其中的原因,今天就来整理一下。 首先JAVA是一种解释型语言,也就是说JAVA并不能直接被编译连接成机器语言执行,而是被编译成二进制的.class字节码文件,再由java虚拟机解释执行,这中间就有了字节码加载的开销,和解释字节码的时间开销。...

qq_41086588的博客 1607

告别裸机:在FreeRTOS上为STM32移植SOEM EtherCAT主站的思路与实战

本文详细介绍了在FreeRTOS环境下为STM32移植SOEM EtherCAT主站的工程实践。通过重构任务调度模型、优化内存管理和中断响应,成功将通信周期抖动控制在±100ns以内,满足工业控制系统的严苛实时性要求。文章包含完整的移植策略、性能优化方法和实测数据,为开发者提供了一套可靠的EtherCAT主站解决方案。

weixin_30342363的博客 388

java运行速度比C++慢的原因

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

无为 2212

VS2015+C++实战:手把手教你用海康MVS里的Demo搞定多相机同步采图与保存

本文详细解析了在VS2015+C++环境下,利用海康威视MVS工业相机SDK实现多相机同步采图与保存的全流程。从环境准备、SDK选择到多相机初始化、同步采图方案,再到异常处理与性能优化,提供了实战技巧和代码示例,帮助开发者快速掌握工业相机二次开发的核心技术。

weixin_29170327的博客 280

COMSOL仿真教程—激光烧蚀

本例使用二维模型,将来自激光的入射热通量模拟为金属表面上空间分布的热源,从而得到金属的烧蚀过程和瞬态温度分布。

qq_40977332的博客 2万+

为什么Java比C++慢?

Why Java Will Always Be Slower than C++ by Dejan Jelovic   "Java is high performance. By high performance we mean adequate. By adequate we mean slow."- Mr. Bunny   Anybody that has ever used a n

Dony的专栏 1632

数据安全实战技能解析:从加密攻防到数字水印的竞赛指南

数据安全是信息安全领域的核心,其基础在于密码学与信息隐藏技术。密码学通过加密算法(如AES、RSA)和哈希函数,保障数据的机密性与完整性,其原理涉及对称/非对称加密、工作模式及密钥管理。数字水印技术则基于信号处理(如DCT/DWT变换),将信息嵌入多媒体载体,用于版权保护与溯源。这些技术的价值在于为数据全生命周期提供“防泄漏”与“可追溯”的解决方案,广泛应用于企业数据治理、合规审计和**数据防泄漏(DLP)** 系统。本文以一场贴近实战的**数据安全职业技能竞赛**为切入点,深入剖析如何运用密码分析、磁盘取

weixin_34314962的博客 402

java效率为什么比c/c++慢,蓝桥杯上java只得50分,c++通过?

同时,编程竞赛的得分情况也受到多种因素的影响,包括题目的难度、选手的编程水平、编程风格等。在蓝桥杯等编程竞赛中,C/C++程序员可能更容易写出高效的代码,因为他们可以直接操作内存和硬件,而Java程序员则需要遵循一定的编程规范和约定。4. 题目特点:在某些题目中,可能需要利用到一些特定于C/C++的特性或库函数,这些特性或库函数在Java中可能并不存在或实现方式不同,从而导致Java程序员在解题时面临更大的挑战。Java和C/C++的效率差异以及在不同编程竞赛中的得分情况,是由多种因素决定的。

linlaoshi2009的博客 994

AVL-Excite新手必看:5步搞定发动机阀系系统建模(附B站视频教程)

本文为AVL-Excite新手提供发动机阀系系统建模的5步详细指南,涵盖软件环境搭建、基本结构建立、关键参数设置、仿真分析及常见问题排查。通过清晰的步骤说明和实用技巧,帮助工程师快速掌握建模方法,并附有精选B站视频教程链接,便于实践学习。

weixin_29305313的博客 507

PCIe协议之 Equalization篇 之 谈谈几种模式

对于两端有能力最高支持 32 GT/s 及以上速率的设备,如果把目标速度设置为 8 GT/s 或 16 GT/s 速率,是不建议采用 Bypass-Equalization-to-Highest-Rate 模式的,即便采用了,也不会针对 8 GT/s 或 16 GT/s 的目标速率进行 EQ。对于支持 32 GT/s 及以上速率的设备,其可能根本无需工作在 8 GT/s 或 16 GT/s 速率,这时再针对 8 GT/s 或 16 GT/s 速率进行 EQ,多少有点浪费。

那么菜的博客 562

C++ 的本质·第 10 篇 C++ 的本质总结:为什么它永远不会死

熟练使用各种特性,不被复杂的报错信息劝退。深刻理解RAII零成本抽象和内存模型。明白“为什么这么设计”比“怎么用”更重要。能够像 CPU 一样思考。当你写下一行代码,脑中能浮现出对应的内存布局、缓存命中情况以及可能的汇编指令。Q:既然 C++ 这么难,为什么我们还要用它?A:因为它是唯一一种能在百亿级规模的代码量上,同时提供极致性能、高度抽象和多端兼容的工具。它不保护庸才,但它赋予天才统治硬件的力量。Q:C++ 的未来在哪里?A:在异构计算(Sender/Receiver)和编译期自动化。

腾TO的技术博客 834

ros入门(八)---TF坐标转换

TF(TransForm),就是坐标转换,包括了位置和姿态两个方面的变换。

weixin_51157015的博客 3388

Spring让Java慢了30倍,JIT、AOT等让Java比Python快13倍,比C慢17%

真相很可能和某些群体想象的不一样,偏见是源于认知滞后。Java 的“慢”是一个技术神话,其根源是:时间差:用 2004 年的 Java 对比 2024 年的 Python对象错:把 Spring 的慢当作 Java 的慢测量错:在 JIT 预热阶段下结论信息差:不知道 ZGC、GraalVM、Quarkus 的存在定位差:Java 要和所有的语言比,却忽略了它的跨平台以及成熟的社区作为技术人员,我们确实应该持续学习,要知道 JDK 每 6 个月一个版本,性能优化日新月异。

m0_69632475的博客 593

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

为什么我感觉永远满足不了公司的要求?

先看再点赞,给自己一点思考的时间,微信搜索【沉默王二】关注这个靠才华苟且的程序员。 本文 GitHub github.com/itwanger 已收录,里面还有一线大厂整理的面试题,以及我的系列文章。 二哥,你好啊,为什么我感觉永远满足不了公司的要求?我是 2017 年学的 Java,但因为没有人带,到年末才敲得出 Hello World,2018 年上半年报了培训班学了前端,还有 Java SE 和 Java EE,以及 MySQL,投了一些简历结果遇到了很多培训机构;2019 年感觉基础不足,比如 .

沉默王二 4149

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

JAVA 字符串比较 C++程序员转JAVA开发永远的痛

JAVA 字符串比较 C++程序员转JAVA开发永远的痛

小兵的专栏 1021

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

为什么 C++ 有指针了还要引用?

今天师弟问我,引用的底层也是指针实现的,内置类型指针传递和引用传递的汇编代码是一样的,那C++为什么还需要引入引用呢? 好吧,仔细想了下,这确实是个好问题。 引用传递,只是明面上,没有使用值传递,值传递本身是不可避免的。 编译器,暗地里通过指针(或者其他可以替代指针的数据类型)的值传递,替换了引用传递。 所以引用传递,实质上是地址传递,别名这东西只是概念,是一种抽象,别名是没法传递的。 别名,可不...

a3192048的博客 1万+

取代java_为什么C++没有被java取代

关于java虚拟机和Class文件格式, 貌似很厉害的样子,那肯定有人疑问,为什么 c/c++这些不能跨平台的语言,还现在还被很多人使用,还没被java取代呢。当然,这个原因有很多,比如java的gc过程所无法避免的stop the world过程,这在 某些实时性要求比较高的 系统中,比如 股票交易系统,军事系统,是不可接受的。(关于垃圾回收这是另一个话题,不在本文范围内,未来有时间可以花时间另...

weixin_39738667的博客 523

java程序解析文件慢_为什么Java比C ++更快地读取大文件?

我有一个2GB的文件(iputfile.txt),其中文件中的每一行都是一个单词,就像:appleredbeautifulsmellsparkinput我需要编写一个程序来读取文件中的每个单词并打印单词计数。 我使用Java和C ++编写它,但结果令人惊讶:Java运行速度比C ++快2.3倍。 我的代码如下:C ++:int main() {struct timespec ts, te;doub...

weixin_42523326的博客 527

在什么情况下,Java比C++慢很多?

问:在什么情况下,Java 比 C++ 慢很多?答:Ben Maurer:为了回答这个问题,需要先将该问题分成几个可能引起慢的原因:垃圾回收器。这是一把“双刃剑”。如果你...

哲洛不闹的专栏 377

Java来抢饭碗,C++可别生气

                                     Java来抢饭碗,C++可别生气Java之好,因为它描绘了Internet的未来;Java之坏,因为它是Sun的私有财产,是一家之言。看过《Thinking in Java》这本权威教学著作,你会惊讶竟有一种语言会有如此多的问题,你会认为Java还只是羽翼未丰的雏鸟。是的,Java是OOP,但这并不说明它象C++那样经典

Dev in Nightmare 1818

边用llama.cpp边学C++:Windows 11下真实工程驱动的入门路径

C++是一门强工程导向的语言,其核心价值在于对内存、硬件和系统资源的直接掌控。理解std::vector的RAII语义、std::thread的生命周期管理、CUDA与CPU协同的构建逻辑,远比孤立记忆语法更重要。llama.cpp作为轻量级但工业级的大模型推理引擎,天然融合了现代C++关键特性(如constexpr、模板元编程、跨平台条件编译)与底层实践(mmap内存映射、AVX指令对齐、OpenMP并发优化),成为连接语法知识与真实系统行为的理想桥梁。尤其在Windows 11 + CUDA环境下,从编

weixin_33700350的博客 407

JAVA,永远滴神

1.你好,JAVA Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。 Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等 。 一、关于JAVA的环境搭建问题 (1

Mustang1998的博客 435

永远支持C++

C++,梦寐以求的课程终于到来了,终于和seven上同样的课程了。 在三门面向对象程序设计课程(C++,JAVA,C#)中必选一门,我自然毫不犹豫地选了C++,从此开始了我的C++之路,我想我会在这条路上一直走下去,在任何情况下我都不会放弃C++。 至于面向对象程序设计,之前一直不知道这是怎么一回事,刚开始学C++我以为是再学习一种语言,只不过这种语言更强大而已。在第一节课上,马锐老师给我们介

无知的我 1612
上一篇: Java即时编译和逃逸分析(及Java相对于c/c++慢的原因)
下一篇: 大众点评 链路监控cat源码的几个片段分析(初始化 messageId的传递)
琅琊山二当家
博客等级 码龄18年 447粉丝 322原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值