首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Java 优化技术(8)

Java 优化技术(8)

再次运行程序可以在         meteor.caching 包中找到我们的解拼图程序的这个更新版本的源代码。运行         java meteor.caching.Solver 表明我们再次极大地改进了性能。在我们的测试机器上,用 25 秒找到了所有解决方案。高速缓存使速度提高了 6 倍。如果我们使用         -verbose:gc 开关,则还会看到垃圾收集已不成问题。      
我们引入以实现高速缓存的额外代码明显使程序变复杂了。这是尝试通过存储中间结果来减少计算时间的性能技术的典型缺点。但在这种情况下,性能改进的效果似乎超过了增加代码复杂程度的代价。
编程优化我们的解拼图程序的优化过程的最后一步可能是使用低级别 Java 代码优化习惯用法。我们并不在应用程序中操作任何字符串,因此应用众所周知的         StringBuffer 习惯用法是没有用的。我们可以通过使用直接成员访问替换读方法(getter)和写方法(setter)以避免那些读方法和写方法的方法调用开销。但是,这显然降低了代码的质量,测试显示这几乎对提高速度没有任何帮助。对于使用         final 方法,也是如此。通过将我们的方法声明为         final 避免了动态绑定并允许 Java 虚拟机使用更有效的静态绑定。但是,哎!这也未能明显地提高速度。同样,使用 Java 编译器的         -O 优化开关没有产生任何实际的性能改进。      
通过改进         prune() 方法的实现仍然可以略微提高执行速度。  中的代码总是调用递归的         getIslandSize() 方法,即使图板单元已被处理或不为空。如果我们在调用         getIslandSize() 之前就提前完成这些检查,则会使速度提高百分之十。      
从这个讨论可以明显地看出,低级别优化带来很小的性能改进。低级别优化对性能的改进不显著,加上其中一些优化技术会损害代码质量,从而导致了低级别优化的使用缺乏吸引力。
结束语改进我们的解拼图程序实现的所有工作当然得到了回报。表 1 总结了我们创建的不同版本及其执行时间。总体结果令人惊奇,速度提高了 2,000,000 倍。
表 1. 比较执行时间版本时间(秒)meteor.initial~ 60,422,400(大约 2 年)meteor.algorithm157meteor.caching25
无论该优化给人的印象多么深刻,重要的问题是我们可以从这个试验中学到什么?我们使用的每种不同的优化技术都各有利弊。将它们组合到单个优化过程阐明它们的使用并且避免了混乱的应用:
  • 我们使用的象 这类高级优化技术具有很大潜力。如果您需要优化性能关键型代码块,请首先尝试分析这一代码实现的过程。使该过程可视化是更好地理解该过程的出色方法。也请尝试从不同的角度处理该问题。您可能提出比您初始设计的解决方案好得多的解决方案。这类优化的一个明显的困难是难于一般化。每个算法都特定于特殊应用程序领域,因此能够提供的通用指导原则几乎没有。这取决于程序员是否有创造力。
  • 一旦您确定有了好的有效的解决方案,则是时候应用 了。基本思路是用          数据复杂度换取          时间复杂度。对象高速缓存是这类技术中最典型的技术。在 Java 程序中,对象高速缓存特别有用,因为它们帮您避免了耗费巨大的对象创建和垃圾收集开销。记住,此类系统向您的程序中添加了额外的基础结构代码,因此不要过早引入它。代码越复杂,就越难以优化。
  • 最后,我们可以应用一定范围的 。大多数 Java 程序员熟悉这类技术。但在大多数实际程序中,它们的优势有限。尽可能地使用它们,但是不要把您的所有优化工作都集中于此类习惯用法。它们应该是帮助您避免已知的性能陷阱的编程工具集的一部分。
我们在解拼图程序中通过组合不同的优化技术极大地改进了性能,这一成功应该激励所有 Java 程序员研究他们自己的代码以及如何对其进行优化。
返回列表