Shell's Home

Jan 26, 2007 - 1 minute read - Comments

关于Java和C++的一点争论

不知道为什么,大家好像都喜欢争来争去。关于Java和C++的优劣不知道听了多少。碰巧我两者都会,怎么说也算是公平了吧。我就大着胆子,比较下两者的情况。

对程序而言,速度不是最终要素。否则我们都应该去用汇编不是?一个程序有六个特性,易学,易用,安全,高效,可变,成本低。然而他们一般都是两两冲突的,好学了,就不好用。强大了,就不好学。安全了,自然要执行很多检查,高效了,自然不安全。针对某个平添优化了,可变性就很差,又不能移植,又不好修改。成本低了,自然什么都差。

往往我们写企业应用的时候,都看重可变,低成本,安全,易用。高效呢?企业有钱买大服务器啊,这样的话效率差的不是太多也能接受。易学呢?企业有钱搞推广培训啊,只要有什么功能就加什么功能,不用考虑学不会。写用户应用的时候,则是看重安全,高效,然后易学易用里面要占据一样。可变呢?用户应用有多大?不行重写一个。低成本呢?这就是比较吊诡的事情了,没有啥经济效益的用户程序,往往是写起来最不怕费时最不管经济效益的。

首先从性能角度来说。也许C++程序员说到这里就得意了,不过先别高兴。如果单论速度,汇编语言还在C之上呢。现在网络上很多人讲C优化好了比汇编快,Java优化好了比C快。听听都要笑掉大牙的。C再怎么快,完成同样的步骤,都需要这些汇编代码。Java再怎么快,完成一个动作,底下C代码也不会少的。所谓Java优化好了能快过C,不过是一个Java高手一门心思搞优化,加上碰到一个C语言白痴而已。

我们先不讨论上面问题,就一般Java程序员和C++程序员而言(注意为啥我没说是C程序员,因为能自称纯C程序员的人要么非常精通语言,不会使用C++特性,要么就根本是个白痴),Java程序员编写出的代码效率比C++大约慢5倍上下。这个数据是我个人写两个程序,一个运算,一个读取处理,对比出来的。都是没有优化的代码。经过极端的优化后,C++的代码我大概提高了4-8倍的速度。可惜我不是个很好的Java程序员,Java代码的速度大概提升了一倍还不足。就是说,最终C++代码比Java快了将近15倍。

但是C++程序员们先别乐,首先我Java语言并不好,这还不是最终的速度比。其次我牺牲了C++的很多特性。运算上几乎就是在写汇编了,接口都直接用了WIN32SDKAPI。没有移植性,没有可维护性,还需要特殊的技巧,怎么想都是牺牲重大。如果要真的这么追求速度,相信汇编会是更好的选择。我们在速度相差5倍左右的情况下就可以使用C++而不用汇编,为什么不能在速度相差5倍的情况下选择Java呢?

然后我们再看性能的另外一个方面,存储管理。说简单点,就是外围设备吞吐管理和内存管理。这方面上C++也是远远超越了Java。不需要的内存就不要,不必须的吞吐就不吐。C++是门培养人的语言,没有很好的功底是无法驾驭的。C++是门程序员负责一切的语言,任何错误都是程序员的错误。然而对于Java来说,就不必处理复杂而没有意义的内存管理了。假设一个Java程序员需要传一个对象给子函数,他只要传递就可以了。然而如果C++程序员直接传递,那么就会出现参数拷贝过程。不但效率差,还可能出现错误。单单一个参数传递,就有三种方式。传值,传址,引用。又分成四类,静态动态,常量非常量。交叉起来,总共是12种情况,需要量材选用。如此烦琐的管理方式,我们可以想想对于内存来说是很有好处的。嵌入系统中大型程序设计绝对是C的天下。然而这么困难的使用方式,需要多大的人力成本才能做到呢?这明显的违反了低成本的原则。

Java的内存管理从C++的角度看绝对是具有瑕疵的,内存释放了不管,直到没有空间了才收集。然而很多C++程序高手在特殊情况下,会重载operator

new算子。其中的行为就很类似这个,Java只是将特殊情况下的应用放到了一般情况。这样对于速度的后果就是,很多的缓存会被持续的从物理内存中挤压出去,导致磁盘吞吐效率降低。对于Java程序,我猜测提升效率的瓶颈将会在和系统交互以取得最佳的垃圾收集时间上。

下面的论题就可能是C++程序员所不高兴看到的了,安全性和可变性。

就语言来说,用户输入的检查这种安全性是一点意义都没有的。我们所说的基本包括几个方面,非正常用法安全,线程安全,异常过程安全。就语言来说,分为了解释型和编译型。那么怎么区分呢?我这里有个很简单的方法,如果程序本身能被本身修改,就是编译型的,否则是解释型。注意,不是让你修改了磁盘上的源码再运行。这个能力赋予了C++强大的功能,例如修改游戏,检查病毒,都需要这个能力。但是不可否认的,比起无法修改自身的程序,安全性就差太多了。线程安全性上讲,Java的所有对象都是系统管理的,也就很容易的可以管理互斥。用过C++的都知道,C++自身是没有互斥的,全靠系统的函数库或者第三方库支撑。好用不好用不说,无法移植是一定的!最后是异常过程安全,C++的异常过程是很恐怖的。关键在于C++的异常传递有三种办法,传值,传址,引用。而且在异常过程中还又涉及回了内存管理啥的。天啊,要是异常都不能专心处理异常,我还要异常干嘛?

至于可变性,那就更别说了。连处理异常都要小心内存泄露的家伙,你指望在修改代码的时候轻松到哪里去?C++是具备了强大的可变性,然而处于效率考虑,很多增强可变性的东西是选项的。例如RTTI,居然要开编译器选项的说。需要使用可变性就要牺牲性能,而且还要你小心的使用。如果使用不小心,抱歉,你又陷入效率和安全的问题里面去了。

如果你有很好的系统功底,准备往计算机领域发展(注意不是计算领域)。那么C++是门很好的语言,只是非常费时而已。而且建议你学C#,VB或者Java作为第二语言,选择Bash或者Perl作为第三语言。这样在处理问题上可以事半功倍。如果你打算增加自己的计算机能力,方便日常的电脑使用,而不准备深入学习这个领域。那么只学C#,VB或者Java就足够了。

最后要提到的是易学和易用,这两个特性都是软件设计所赋予的。也就是说,即使是以简单著称的VB.NET,也可以写很好用的程序。以复杂著称的汇编,也可以写很友好的界面。这就不在本文的论题以内了。

Tags: c java oo program

TTS杂论 基础类

comments powered by Disqus