Java 的优雅与 C 的效率 — 这就是 Ada!

作者:Frode Tennebo

Michael Hirsch 在他的文章 “比较 Linux 的 Java 实现” (LJ 2000 年 8 月) 中,寻找“一种既有 Java 的优雅性又有 C 的效率的编程语言”。这种语言已经存在,它就是 Ada。

Ada 的当前版本 Ada 95 是 Ada 标准的修订版 (Ada 83 是最初的 ANSI/ISO 标准)。它在 C++ 和 Java 仍处于早期阶段时就已标准化。Ada 通常被认为是一种笨重、过时的语言,既没有 Java 的酷炫,也没有 C++ 的严谨。然而,Ada 是一种强大而现代的语言。

Ada 除了自身的一些特性 (例如泛型和运算符重载) 外,还具有 Java 的所有特性。实际上,Ada 在一种语言中提供了 Java C++ 的所有特性 (除了对多重继承的直接支持),他们的网站 (参见“资源”) 提供了对这些语言的良好比较。您甚至可以从 Ada 源代码构建 j-code applet。因此,您拥有 Java 的所有优点以及更多。

Ada 是一种强类型语言,如果使用得当,可以产生更清晰的代码和更易于维护的程序。结果是,错误可以在编译时而不是调试时轻松检测到。有关 Ada 语言的更多信息,请访问他们的网站。

有许多 Ada 编译器供应商,您可以为几乎任何平台获得一个编译器,而且,它可以交叉编译到 (几乎) 任何其他平台。最著名的供应商是 Rational、Aonix、R. R. Software 和 Green Hill Software (参见“资源”)。

然而,Michael Hirsch 也想要一个开源项目。作为回应,Ada Core Technologies 的 GNAT 对于 Ada 来说,几乎就像 gcc 对于 C/C++ 一样。GNAT 几乎完全用 Ada 编写,并使用 gcc 代码生成器。GNAT 的公共版本 (有关下载站点,请参见“资源”) 根据 FSF copyleft 许可证分发。ACT 还根据支持合同提供其编译器的非公共版本。

我已经编写了与 Michael Hirsch 的 Java 和 C++ 程序等效的 Ada 程序,如清单 1 所示。正如您所见,该清单具有很高的可读性,并且看起来非常像 Java 和 C++ 程序。它分为三个单元:包规范 (类似于 C 头文件)、包体和主程序 (一个过程)。Ada 对哪些内容进入哪个单元有明确的规则,GNAT 通过要求每个单元都位于单独的文件中来强制执行此规则,其中文件名必须是包/过程名称,规范后缀为 .ads,包/过程后缀为 .adb。

清单 1. Java 和 C++ 程序的 Ada 等效程序

您可以将示例 (或下载它) 输入到一个文件中,并运行 GNAT 发行版中包含的实用程序 gnatchop。这将把文件拆分为三个所需的文件,并带有各自的文件名。要编译和链接,您可以使用特别修改的 GNAT 版本的 gcc,但更实用的是使用 gnatmake 实用程序。只需输入:gnatmake perftest,gnat 将编译所需的单元,然后绑定和链接主过程。

由于我没有与作者相同的硬件,因此我在两台 Linux 机器和一台十英寸 Sun Ultra 上,除了 Ada 基准测试外,还执行了相同的 Java 和 C++ 基准测试。结果如表 1 所示;经过的时间是每毫秒的对象数。

使用的 Ada 编译器是 Gnat 3.12p、Gnat 3.13p 和 JGNAT 1.0p (p = public)。后两者是在撰写本文时刚刚发布的。请注意,还有其他 Ada 编译器生成的executables可能比 GNAT 编译器运行得更快或更慢。

表 1. Ada、Java 和 C++ 基准测试结果

JGNAT 是一种特殊的工具,因为它将 Ada 代码编译成 Java 字节码,而 Java 字节码又可以在任何 JVM 上运行。正如您所见,它仅比 SUN JDK 慢约 15%,而 JRE 1.2.01 实际上更快!这还是对于使用 GNAT 编译器编译的完全相同的代码,使用 JGNAT 编译器的第一个版本而言!情况只会变得更好。

我尝试在 Linux 上使用 kaffe 运行 JGNAT 编译的程序,但得到

[ft@modesty jtest]$ ~/kaffe/bin/java perftest@bbKaffe: mem/gc-incremental.c:823: gcMalloc: Assertion <\#145>fidx < nrTypes
&&
size != 0' failed.

这表明 kaffe 中存在一个错误。

关于 Ada 一般和 GNAT 特别说明:默认情况下,编译器会在编译时进行许多运行时测试,以确保一切顺利进行。因此,如果出现问题,它可以采取受控操作以避免程序过早终止。通常,该操作是引发异常。-gnatp 禁用许多这些测试,因此,使程序运行得更快。我不建议这样做,但这确实为与 C++ 速度进行更好的比较提供了条件。

对于此特定测试,Ada 平均比 C++ 慢约 19%。在 Sun 平台上,使用可比较的代码生成器 (GNAT 使用 gcc 2.8.1 作为其基础),这降至约 8%。请注意,这是一个 非常 有限的测试,它仅表明 Ada 可以产生与 C++ 相当的运行速度。在某些情况下,Ada 实际上会比 C++ 对应程序运行得更快。我猜想差异将趋于平缓,可能略微对 C++ 有利。通常的免责声明适用。

然而,在开发以及后期的维护中,使用 Ada 可以获得真正的节省。有关 Ada 83 和 C 之间的全面比较,请参阅 www.rational.com/products/whitepapers/337.jsp

结论

如果您想要一种既有 Java 的优雅性 (以及更多) 又有 C/C++ 的速度的编程语言 - 请看看 Ada。它甚至可以生成 Java 字节码。

资源

Elegance of Java and the Efficiency of C—It's Ada!
Frode Tennebø (frodet@nvg.org) 居住在挪威哈尔登。他于 1994 年首次接触 Linux,此后一直是 Linux 爱好者。他在当地的 LUG 委员会中占有一席之地。目前,他将大部分空闲时间与他五个月大的女儿在一起,留给计算机的时间更少了。
加载 Disqus 评论