java和C代码运⾏效率的⽐较(整理)
最近和朋友⽆意间讨论起了有关java 和C 的效率问题,(我是java 推介者,他是 c 语⾔推介者,他做的是嵌⼊式)
故,想通过⽹络查询⼀下,总结⼀下,两者到底效率如何,其有何差异,原因⼜是啥?各种优势有在何处?
1 Java 语⾔的概述
作为⼀种⾯向对象的程序设计语⾔,Java 与 C++极为类似,但却要⽐ C++简单的多。它在集成其他语⾔的特点和优势的同时⼜有⾃⼰独特的优势。
Java 的主要特点如下:
(1)简单性。Java 可以对内存中产⽣的垃圾进⾏⾃动收集,⼤幅度降低了程序的复杂程度,此外,Java 添加了更为实⽤的功能的,这使得程序开发更加简单可靠。
(2)平台独⽴性。Java 语⾔在程序编程过程中是先编译成中间码,然后再进⾏装载与校验,最后通过翻译出来的不同的机器码来执⾏。因此,只要能⽀持 Java 虚拟机,就可运⾏各种 J ava 程序。这也是 Java 最吸引⼈、使⽤⽅便的原因。
(3)⾯向对象的技术。近年来软件开发中使⽤最多的就是⾯向对象的技术。⾯向对象技术是指在编程过程中,以⼀种更加直观的、⼈们更容易接受的⽅式来编程的技术。⽽ Java 的动态联⽹编程特性,将⾯向对象的优势发挥到最⼤。
2 C 语⾔的概述
C 语⾔,作为⼀种新的程序设计语⾔,它结合了汇编语⾔与⾼级语⾔两种语⾔的优势,使得它的应⽤更加简单、普及。如今,C 语⾔已经应⽤于各种类型的微型机上。在编写程序时,C 语⾔可以直接进⾏程序的编程。因此,C 语⾔在应⽤⽅⾯⼗分⼴泛,具备很强的数据处理能⼒。C 语⾔的应⽤已不仅仅是⽤于软件开发,各类科研都需要⽤到 C 语⾔。
C 语⾔的优点:1.是简洁紧凑、灵活⽅便;2.运算符丰富;3.数据类型丰富;4.表达⽅式灵活多⽤;5.⽣成⽬标代码质量⾼、程序执⾏效率⾼;可移植性⾼。
因为 C 语⾔是将相同数据堆放在⼀块,这就使得 C 语⾔的数据存在很⼤的安全缺陷,⼀旦出现意外,所有数据都将丢失。
此外,C 语⾔在语法限制以及变量的类型上⽐较宽松,这样就会影响到程序的安全性。⽽且 C 语⾔⽐其他⾼级语⾔的难度⼤,完全掌握是很不易的。
3.c 和 java的编译器对⽐
Java与C/C++的编译器对⽐实际上是代表了最经典的与静态编译器的对⽐,
(注释:JIT,英⽂写作Just-In-Time Compiler,中⽂意思是即时编译器。JIT编译器能够将MSIL编译成为各种不同的机器代码,以适应对应的系统平台,最终使得程序在⽬标系统中得到顺利地运⾏。静态编译,就是编译器在编译可执⾏⽂件的时候,将可执⾏⽂件需要调⽤的对应(.so或.lib)中的部分提取出来,链接到可执⾏⽂件中去,使可执⾏⽂件在运⾏的时候不依赖于动态链接库。)
也很⼤程度上决定了Java与C/C++的性能对⽐的结果,
因为⽆论是C/C++还是Java代码,最终编译之后被机器执⾏的都是本地机器码,哪种语⾔性能更⾼,除了它们⾃⾝的API库实现得好坏以外,其余的⽐较就成了⼀场“拼编译器”、“拼输出代码质量”的游戏。
当然,这种⽐较也是剔除了开发效率的⽚⾯对⽐,语⾔间孰优孰劣,谁快谁慢的问题都是很难有结果的争论,下⾯我们就回到正题,看看这两种语⾔的编译器各有何优势。
原因如下:
(1)因为JIT编译器运⾏占⽤的是⽤户程序运⾏时间,具有很⼤的时间压⼒,它能提供的优化⼿段也严重受制于编译成本。如果编译速度不能达到要求,那⽤户将在启动程序或程序的某部分察觉到重⼤延迟,这点使得JIT编译器不敢随便引⼊⼤规模的优化技术,⽽编译的时间成本在静态优化编译器中并不是主要的关注点。
(2),Java语⾔是动态的类型安全语⾔,这意味着需要由虚拟机来确保程序不会违反语⾔语义或访问⾮结构化内存。在实现层⾯上看,这就意味着虚拟机必须频繁进⾏动态检查,如对象实例访问时检查空指针、数组元素访问时检查上下界范围、类型转换时检查继承关系等等。对于这类程序代码没有明确写出的检查⾏为,尽管编译器会努⼒进⾏优化,但是总体上仍然要消耗着不少的运⾏时间。
(3)Java语⾔中虽然没有virutal关键字,但是使⽤虚⽅法的频率却远远⼤于C/C++语⾔,这意味着运⾏时对⽅法接收者进⾏多态选择的频率要远远⼤于C/C++语⾔,也意味着JIT编译器在进⾏⼀些优化,如⽅法内联时难度要远⼤于C/C++的静态优化编译器。
(4)Java语⾔是可以动态扩展的语⾔,运⾏时加载新的类可能改变程序类型继承关系,这使得很多全局的优化都难以进⾏,因为编译器⽆法看见程序的全貌,许多全局优化措施都只能以激进优化的⽅式来完成,编译器不得不时刻注意并随着类型变化⽽在运⾏是撤消或重新进
⾏⼀些优化。
(5)Java语⾔中的对象内存分配都是堆上进⾏,只有⽅法中的局部变量才在栈上分配。⽽C/C++的对象则有多种内存分配⽅式,既可能在堆上分配,也可能在栈上分配,如果可以把线程私有的对象在栈上分配,将可以减轻内存回收的压⼒,也不需要考虑内存屏障⽅⾯的问题。另外,C/C++中主要由⽤户程序代码来回收分配的内存,这就不存在⽆⽤对象筛选的过程,因此效率上(仅指运⾏效率,排除了开发效率)也垃圾收集机制要⾼。
(6)因为C是编译型的,直接将源码编译成机器代码;⽽JAVA是解释型,源码被编译成⼆进制伪代码,由JAVA虚拟机解释执⾏。但是,由于C是编译型的,它的可移植性差;⽽JAVA是解释执⾏,因此具有很好的移植性,可跨平台运⾏。
同时:编⼀个普通的本地应⽤程序,⼀般c 要快于java,编web应⽤,由于c实现的cgi程序基本是进程型,⽽java application server 的管理servlet采⽤线程⽅式,所以,在访问量⼤的情况下,java有优势。
(finally)Java语⾔相对C/C++的劣势上⾯说了⼀⼤堆,倒不是说Java就真的不如C/C++了,相信⼤家也注意到了,Java语⾔的这些性能上的劣势都是为了换取开发效率上的优势⽽付出的代价,动态安全、动态扩展、垃圾回收这些“拖后腿”特性都为Java语⾔的开发效率作出了很⼤贡献。何况,也不见得就没有Java的JIT编译器能做,⽽C/C++的静态优化编译器不能做的优化:由于C/C++编译器的静态
性,以运⾏期性能监控为基础的优化措施它都⽆法进⾏,如调⽤频率预测(Call Frequency Prediction)、分⽀频率预测(Branch Frequency Prediction)、裁剪未被选择的分⽀(Untaken Branch Pruning)等,这些都会形成⼀些Java语⾔独有的性能优势
4.Java程序⽐C/C++程序慢的影响因素
1)解释性语⾔固有开销:java程序在运⾏时类加载器从类路经中加载相关的类,然后java虚拟机读取该类⽂件的字节,执⾏相应操作.⽽C 编译的时候将程序编译成本地机器码.⼀般来说java程序执⾏速度要⽐C 慢10-30倍.即使采⽤just-in-time compiling (读取类⽂件字节后,编译成本地机器码)技术,速度也要⽐C 慢好多.
2)字节码加载执⾏开销:java程序要从⽹络上加载类字节,然后执⾏,这也是导致java运⾏速度慢的原因.
c++string类型3)运⾏时溢出检测开销:在程序运⾏过程中,java虚拟机要检测数组是否越界,在C 中则不检测.
4)堆与栈的区别:java中所有的对象都创建在堆中,没有对象被创建在stack中,⽽C 有的对象和变量是创建在stack中的
5)运⾏时引⽤检测开销:java在运⾏过程中检测对象的引⽤是否为空,如果引⽤指向都空指针,且执
⾏某个⽅法时会抛出空指针异常
6)运⾏时类型检测开销:java运⾏时对类型检测,如果类型不正确会抛出ClassCastException异常.
7)GC巨⼤开销:java的垃圾回收机制较C 由程序员管理内存效率更低.
8)类型转换开销:java中的原始数据类型在每个操作系统平台长度都是相同,⽽C 这些数据类型长度是随操作系统的不同⽽不同,所以java在不同操作系统上执⾏时有个转化过程.
9)String类型开销:在java中String 是UNICODE.当java要操作⼀个 ASCII string 时,⽐C 效率上相对要低⼀些.
10)动态链接开销:java中采⽤的是动态链接
5 结论
综上所述,C 语⾔的运⾏效率要⽐ Java 的⾼很多(有⼈说是⾼10-30倍)。因为 C 语⾔是属于编译型的,⽽ Java 语⾔则是解释型的。Java 语⾔运⾏时要先被翻译成计算机能辨识的⼆进制代码,然后才能执⾏。虽然在⼀些的程序测试中 C 语⾔要快于Java 语⾔,但这并不是绝对的。在实际中,要根据不同语⾔应⽤范围,才能选择某⼀语⾔程序。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论