首页 | 资讯动态 | linux基础 | 系统管理 | 网络管理 | 编程开发 | linux数据库 | 服务器技术 | linux相关 | linux认证 | 嵌入式 | 下载中心 | 专题 | linux招聘 | 镜像站
OKLinux中文技术站
·设为首页
·加入收藏
·联系我们
系统管理: 中文环境 系统管理 桌面应用 内核技术 | Linux基础: 基础入门 安装配置 常用命令 经验技巧 软件应用 | Linux数据库: Mysql Postgre Oracle DB2 Sybase other
网络管理: 网络安全 网络应用 Linux服务器 环境配置 黑客安全 | 编程开发: PHP CC++ Python Perl Shell 嵌入式开发 java jsp | PHP技术: PHP基础 PHP技巧 PHP应用 PHP文摘
搜索中心 Linux招聘 Linux专题 Apache | Linux相关: 硬件相关 Linux解决方案 Linux认证 企业应用 其它Unix | 相关下载: 资料下载 参考手册 开发工具 服务器类 软路由 其它
 技术搜索:
会员中心 注册会员 高级搜索  
  → 当前位置:首页>编程开发>java>Java基础>正文

教你轻松提高Java代码的性能

http://www.oklinux.cn  2008-09-19  ccidnet 小N  会员收藏  游客收藏  【 】 
您查看的文章来源于http://www.oklinux.cn

尾递归转换能加快应用程序的速度,但不是所有的JVM都会做这种转换,很多算法用尾递归方法表示会显得格外简明。编译器会自动把这种方法转换成循环,以提高程序的性能。但在Java语言规范中,并没有要求一定要作这种转换,因此,并不是所有的Java虚拟机(JVM)都会做这种转换。这就意味着在Java语言中采用尾递归表示可能导致巨大的内存占用,而这并不是我们期望的结果。Eric Allen在本文中阐述了动态编译将会保持语言的语义,而静态编译则通常不会。他说明了为什么这是一个重要问题,并提供了一段代码来帮助判断您的即时(JIT)编译器是否会在保持语言语义的同时做尾递归代码转换。

尾递归及其转换

相当多的程序包含有循环,这些循环运行的时间占了程序总运行时间的很大一部分。这些循环经常要反复更新不止一个变量,而每个变量的更新又经常依赖于其它变量的值。

如果把迭代看成是尾递归函数,那么,就可以把这些变量看成是函数的参数。简单提醒一下:如果一个调用的返回值被作为调用函数的值立即返回,那么,这个递归调用就是尾递归;尾递归不必记住调用时调用函数的上下文。

由于这一特点,在尾递归函数和循环之间有一个很好的对应关系:可以简单地把每个递归调用看作是一个循环的多次迭代。但因为所有可变的参数值都一次传给了递归调用,所以比起循环来,在尾递归中可以更容易地得到更新值。而且,难以使用的 break 语句也常常为函数的简单返回所替代。

但在 Java 编程中,用这种方式表示迭代将导致效率低下,因为大量的递归调用有导致堆栈溢出的危险。

解决方案比较简单:因为尾递归函数实际上只是编写循环的一种更简单的方式,所以就让编译器把它们自动转换成循环形式。这样您就同时利用了这两种形式的优点。

但是,尽管大家都熟知如何把一个尾递归函数自动转换成一个简单循环,Java 规范却不要求做这种转换。不作这种要求的原因大概是:通常在面向对象的语言中,这种转换不能静态地进行。相反地,这种从尾递归函数到简单循环的转换必须由 JIT 编译器动态地进行。

要理解为什么会是这样,考虑下面一个失败的尝试:在 Integers 集上,把 Iterator 中的元素相乘。

因为下面的程序中有一个错误,所以在运行时会抛出一个异常。但是,就象在本专栏以前的许多文章中已经论证的那样,一个程序抛出的精确异常(跟很棒的错误类型标识符一样)对于找到错误藏在程序的什么地方并没有什么帮助,我们也不想编译器以这种方式改变程序,以使编译的结果代码抛出一个不同的异常。

清单 1. 一个把 Integer 集的 Iterator 中的元素相乘的失败尝试

 

  import java.util.Iterator; 

  public class Example { 

  public int product(Iterator i) { 

  return productHelp(i, 0); 

} 

  int productHelp(Iterator i, int accumulator) { 

  if (i.hasNext()) { 

  return productHelp(i, accumulator * ((Integer)i.next()).intValue()); 

  } 

  else { 

  return accumulator; 

  } 

  } 

  }

注意 product 方法中的错误。product 方法通过把 accumulator 赋值为 0 调用 productHelp。它的值应为 1。否则,在类 Example 的任何实例上调用 product 都将产生 0 值,不管 Iterator 是什么值。

共3页: 上一页 1 [2] [3] 下一页

上一篇:Java开发最容易犯的几种错误   下一篇:2008软件自由日 开源向左,私有向右

收藏于收藏夹】 【评论】 【推荐】 【打印】 【关闭
相关文档
·Java开发最容易犯的几种错误
·Java开发中static/this/super/final用法
·网友分享:关于提高自己Java水平十大技术
·Java程序员必须要了解的七个开源协议介绍
·网友经验分享:学好java开发的关键七步
·对于Java开发人员必须遵从的十大基本法则
·Java基础:Java/J2EE中文问题终极解决之道
·初学者学习java第一步——JDK环境变量配置
·代码简单描述 初学Java语言之多态初体验
·教你如何妙用EditPlus 配置Java编译环境
·一个优秀Java程序员必须了解的GC工作原理
·JAVA和.NET两个平台对于安全功能的比较
·Java课堂:初学者都必须理解的几个问题
·基础知识:Java Web三层架构的配置详解
·区分Tomcat与Web服务器、应用服务器的关系
·Java 安全性综述:安全性的基本要点
发表评论
密码: 匿名评论
评论内容:

(不超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规)
 
  最新文档
·Java开发最容易犯的几种错误
·Java开发中static/this/super/final用
·网友分享:关于提高自己Java水平十大技
·Java程序员必须要了解的七个开源协议介
·网友经验分享:学好java开发的关键七步
·对于Java开发人员必须遵从的十大基本法
·Java基础:Java/J2EE中文问题终极解决
·初学者学习java第一步——JDK环境变量
·代码简单描述 初学Java语言之多态初体
·教你如何妙用EditPlus 配置Java编译环
·一个优秀Java程序员必须了解的GC工作原
·JAVA和.NET两个平台对于安全功能的比较
  阅读排行
·使用AJAX技术实现网页无闪自动局部刷新
·高级:lucene全文检索应用示例及代码简
·关于java中相对路径,绝对路径问题总结
·JAVA基础:一个struts hibernate入门实
·Java语言深入--java调用C/C 的过程
·一个非常有趣的使用spring框架AOP例子
·一个基于Java Socket实现文件传输示例
·使用WEBWORK实现文件上传方法实例详解
·初学者Structs中基本配置入门
·快速教您Apache Tomcat SSL的配置
·Hibernate配置文件中的映射元素详解
·在struts里实现dtree通用树型结构讲解
·详细讲解Struts构架中action的跳转大全
·用JSP JavaScript打造二级级联下拉菜单
·基于AJAX的动态树型结构的设计与实现
网摘收藏: