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编译器静态编译器的对比,

(注释: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运行速度慢的原因.

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 语言,但这并不是绝对的。在实际中, 要根据不同语言应用范围,才能选择某一语言程序。

posted @ 2017-04-13 10:28  dy9776  阅读(20545)  评论(3编辑  收藏  举报