当前位置:七道奇文章资讯编程技术Java编程
日期:2011-03-22 16:16:00  来源:本站整理

java的性能[Java编程]

赞助商链接



  本文“java的性能[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:

“本附录由Joe Sharp投稿,并得到他的赞成在这儿转载.请接洽SharpJoe@aol.com”

Java语言分外夸大精确性,但坚固的行为要以性能作为代价.这一特点反映在自动汇集垃圾、严峻的运行期查抄、完好的字节码查抄以及保守的运行期同步等等方面.对一个注释型的虚拟机来说,由于目前有大量平台可供挑选,所以进一步阻碍了性能的施展.
“先做完它,再渐渐完善.好在需求改良的地方普通不会太多.”(Steve McConnell的《About performance》[16])
本附录的目标就是指导大家探求和优化“需求完善的那一部份”.

D.1 基本办法
只有精确和完好地检测了程序后,再可着手办理性能方面的问题:
(1) 在实际环境中检测程序的性能.若符合要求,则目标到达.若不符合,则转到下一步.
(2) 探求最致命的性能瓶颈.这大概要求一定的本领,但全部勤奋都不会白费.如简单地猜想瓶颈所在,并试图举行优化,那么大概是白花时间.
(3) 应用本附录介绍的提速技术,然后返回步骤1.

为使勤奋不至白费,瓶颈的定位是至关重要的一环.Donald Knuth[9]曾改良过一个程序,那个程序把50%的时间都花在约4%的代码量上.在仅一个工作小时里,他改正了几行代码,使程序的履行速度倍增.此时,若将时间持续投入到剩余代码的改正上,那么只会得不偿失.Knuth在编程界有一句名言:“过早的优化是一切麻烦的本源”(Premature optimization is the root of all evil).最明智的做法是克制过早优化的冲动,因为那样做大概遗漏多种有效的编程技术,造成代码更难理解和操控,并需更大的精神举行保护.

D.2 探求瓶颈
为找出最影响程序性能的瓶颈,可采纳下述几种办法:

D.2.1 安插自己的测试代码
插入下述“显式”计时代码,对程序举行评测:

long start = System.currentTimeMillis();
// 要计时的运算代码放在这儿
long time = System.currentTimeMillis() - start;

操纵System.out.println(),让一种不常用到的办法将积累时间打印到掌握台窗口.由于一旦出错,编译器会将其忽视,所以可用一个“静态终究布尔值”(Static final boolean)翻开或关闭计时,使代码能安心留在终究发行的程序里,这样任什么时刻候都可以拿来应急.固然还可以选用更复杂的评测手段,但假如仅仅为了量度一个特定任务的履行时间,这无疑是最简便的办法.
System.currentTimeMillis()返回的时间以千分之一秒(1毫秒)为单位.但是,有些系统的时间精度低于1毫秒(如Windows PC),所以需求反复n次,再将总时间除以n,得到精确的时间.

D.2.2 JDK性能评测[2]
JDK配套供应了一个内建的评测程序,能跟踪花在每个例程上的时间,并将评测后果写入一个文件.不幸的是,JDK评测器并不安定.它在JDK 1.1.1中能正常工作,但在后续版本中却非常不安定.
为运行评测程序,请在调用Java注释器的未优化版本时加上-prof选项.比方:
java_g -prof myClass
或加上一个程序片(Applet):
java_g -prof sun.applet.AppletViewer applet.html
理解评测程序的输出信息并不简单.事实上,在JDK 1.0中,它竟然将办法名称截短为30字符.所以大概无法辨别出某些办法.但是,若您用的平台确切能支持-prof选项,那么可试试Vladimir Bulatov的“HyperPorf”[3]大概Greg White的“ProfileViewer”来注释一下后果.

D.2.3 特别工具
假如想随时跟上性能优化工具的潮流,最好的办法就是作一些Web站点的常客.比方由Jonathan Hardwick制作的“Tools for Optimizing Java”(Java优化工具)网站:
http://www.cs.cmu.edu/~jch/java/tools.html

D.2.4 性能评测的本领
■由于评测时要用到系统时钟,所以当时不要运行其他任何进程或利用程序,免得影响测试后果.
■如对自己的程序举行了改正,并试图(至少在开辟平台上)改进它的性能,那么在改正前后应辨别测试一下代码的履行时间.
■尽大概在完好一致的环境中举行每一次时间测试.
■假如大概,应计划一个不依靠任何用户输入的测试,避免用户的差别反映招致后果呈现偏差.

D.3 提速办法
目前,关键的性能瓶颈应已断绝出来.接下来,可对其利用两种范例的优化:通例手段以及依靠Java语言.

D.3.1 通例手段
普通,一个有效的提速办法是用更实际的方法重新定义程序.比方,在《Programming Pearls》(编程拾贝)一书中[14],Bentley操纵了一段小说数据描写,它可以生成速度非常快、并且非常精简的拼写查抄器,从而介绍了Doug McIlroy对英语语言的表述.除此以外,与其他办法相比,更好的算法大概能带来更大的性能晋升——分外是在数据集的尺寸越来越大的时刻.欲理解这些通例手段的详情,请参考本附录末尾的“普通书籍”清单.

D.3.2 依靠语言的办法
为举行客观的解析,最好明确掌握各种运算的履行时间.这样一来,得到的后果可独立于当前利用的计算机——通过除以花在本地赋值上的时间,最后得到的就是“尺度时间”.

运算 示例 尺度时间

本地赋值 i=n; 1.0
实例赋值 this.i=n; 1.2
int增值 i++; 1.5
byte增值 b++; 2.0
short增值 s++; 2.0
float增值 f++; 2.0
double增值 d++; 2.0
空循环 while(true) n++; 2.0
三元表达式 (x<0) ?-x : x 2.2
算术调用 Math.abs(x); 2.5
数组赋值 a[0] = n; 2.7
long增值 l++; 3.5
办法调用 funct(); 5.9
throw或catch非常 try{ throw e; }或catch(e){} 320
同步办法调用 synchMehod(); 570
新建对象 new Object(); 980
新建数组 new int[10]; 3100

通过自己的系统(如我的Pentium 200 Pro,Netscape 3及JDK 1.1.5),这些相对时间向大家揭暴露:新建对象和数组会造成最沉重的开销,同步会造成对比沉重的开销,而一次差别步的办法调用会造成适度的开销.参考资源[5]和[6]为大家总结了丈量用程序片的Web地址,可到自己的机械上运行它们.

1. 通例改正
下面是加快Java程序关键部份履行速度的一些通例操作倡议(注意比较改正前后的测试后果).

将... 改正成... 来由

接口 抽象类(只需一个父时) 接口的多个担当会阻碍性能的优化
非本地或数组循环变量 本地循环变量 按照前表的耗时对比,一次实例整数赋值的时间是本地整数赋值时间的1.2倍,但数组赋值的时间是本地整数赋值的2.7倍
链接列表(固定尺寸) 保存丢弃的链接项目,或将列表替换成一个循环数组(大致知道尺寸) 每新建一个对象,都相当于本地赋值980次.参考“反复操纵对象”(下一节)、Van Wyk[12] p.87以及Bentley[15] p.81
x/2(或2的肆意次幂) X>>2(或2的肆意次幂) 利用更快的硬件指令

D.3.3 特别情形
■字串的开销:字串通接运算符+看似简单,但实际需求损耗大量系统资源.编译器可高效地衔接字串,但变量字串却要求可观的处理器时间.比方,假定s和t是字串变量:
System.out.println("heading" + s + "trailer" + t);
上述语句要求新建一个StringBuffer(字串缓冲),追加自变量,然后用toString()将后果转换回一个字串.因此,无论磁盘空间还是处理器时间,城市遭到严重损耗.若预备追加多个字串,则可考虑直接利用一个字串缓冲——分外是能在一个循环里反复操纵它的时刻.通过在每次循环里禁止新建一个字串缓冲,可节俭980单位的对象成立时间(如前所述).操纵substring()以及其他字串办法,可进一步地改进性能.假如可行,字符数组的速度乃至可以更快.也要注意由于同步的关系,所以StringTokenizer会造成较大的开销.
■同步:在JDK注释器中,调用同步办法普通会比调用差别步办法慢10倍.经JIT编译器处理后,这一性能上的差别晋升到50到100倍(注意前表总结的时间显示出要慢97倍).所以要尽大概避免利用同步办法——若不能避免,办法的同步也要比代码块的同步稍快一些.
■反复操纵对象:要花很长的时间来新建一个对象(按照前表总结的时间,对象的新建时间是赋值时间的980倍,而新建一个小数组的时间是赋值时间的3100倍).因此,最明智的做法是保存和更新老对象的字段,而不是成立一个新对象.比方,不要在自己的paint()办法中新建一个Font对象.相反,应将其声明成实例对象,再初始化一次.在这今后,可在paint()里需求的时刻随时举行更新.拜见Bentley编著的《编程拾贝》,p.81[15].
■非常:只有在不正常的情形下,才应放弃非常处理模块.什么才叫“不正常”呢?这普通是指程序碰到了问题,而这普通是不肯见到的,所以性能不再成为优先考虑的目标.举行优化时,将小的“try-catch”块归并到一同.由于这些块将代码分割成小的、各自独立的片断,所以会阻碍编译器举行优化.另一方面,若过份热衷于删除非常处理模块,也大概造成代码结实程度的下降.
■散列处理:首先,Java 1.0和1.1的尺度“散列表”(Hashtable)类需求造型以及分外损耗系统资源的同步处理(570单位的赋值时间).其次,早期的JDK库不能自动决意最佳的表格尺寸.最后,散列函数应针对实际利用项(Key)的特点计划.考虑到全部这些缘由,我们可分外计划一个散列类,令其与特定的利用程序配合,从而改进通例散列表的性能.注意Java 1.2调集库的散列映射(HashMap)具有更大的机动性,并且不会自动同步.
■办法内嵌:只有在办法属于final(终究)、private(专用)或static(静态)的情形下,Java编译器才能内嵌这个办法.并且某些情形下,还要求它绝对不可以有部分变量.若代码花大量时间调用一个不含上述任何属性的办法,那么请考虑为其编写一个“final”版本.
■I/O:应尽大概利用缓冲.不然,终究大概就是一次仅输入/输出一个字节的恶果.注意JDK 1.0的I/O类采取了大量同步办法,所以若利用象readFully()这样的一个“大批量”调用,然后由自己注释数据,便可得到更佳的性能.也要注意Java 1.1的“reader”和“writer”类已针对性能举行了优化.
■造型和实例:造型会耗去2到200个单位的赋值时间.开销更大的乃至要求上溯担当(遗传)构造.其他高代价的操作会丧失和恢复更低层构造的本领.
■图形:操纵剪切技术,削减在repaint()中的工作量;倍增缓冲区,提高接纳速度;同时操纵图形压缩技术,缩短下载时间.来自JavaWorld的“Java Applets”以及来自Sun的“Performing Animation”是两个很好的教程.请记着利用最贴切的号令.比方,为按照一系列点画一个多边形,和drawLine()相比,drawPolygon()的速度要快得多.如必须画一条单像素粗细的直线,drawLine(x,y,x,y)的速度比fillRect(x,y,1,1)快.
■利用API类:尽大概利用来自Java API的类,因为它们本身已针对机械的性能举行了优化.这是用Java难于到达的.比方在复制肆意长度的一个数组时,arraryCopy()比利用循环的速度快得多.
■替换API类:有些时刻,API类供应了比我们但愿更多的功效,呼应的履行时间也会增添.因此,可定做分外的版本,让它做更少的事情,但可更快地运行.比方,假定一个利用程序需求一个容器来保存大量数组.为加快履行速度,可将本来的Vector(矢量)替换成更快的动态对象数组.

1. 其他倡议
■将反复的常数计算移至关键循环之外——比方计算固定长度缓冲区的buffer.length.
■static final(静态终究)常数有助于编译器优化程序.
■实现固定长度的循环.
■利用javac的优化选项:-O.它通过内嵌static,final以及private办法,从而优化编译过的代码.注意类的长度大概会增添(只对JDK 1.1而言——更早的版本大概不能履行字节查证).新型的“Just-in-time”(JIT)编译器会动态加快代码.
■尽大概地将计数减至0——这利用了一个特别的JVM字节码.

D.4 参考资源

D.4.1 性能工具
[1] 运行于Pentium Pro 200,Netscape 3.0,JDK 1.1.4的MicroBenchmark(拜见下面的参考资源[5])
[2] Sun的Java文档页——JDK Java注释器主题:
http://java.sun.com/products/JDK/tools/win32/java.html
[3] Vladimir Bulatov的HyperProf
http://www.physics.orst.edu/~bulatov/HyperProf
[4] Greg White的ProfileViewer
http://www.inetmi.com/~gwhi/ProfileViewer/ProfileViewer.html

D.4.2 Web站点
[5] 关于Java代码的优化主题,最超卓的在线参考资源是Jonathan Hardwick的“Java Optimization”网站:
http://www.cs.cmu.edu/~jch/java/optimization.html
“Java优化工具”主页:
http://www.cs.cmu.edu/~jch/java/tools.html
以及“Java Microbenchmarks”(有一个45秒钟的评测历程):
http://www.cs.cmu.edu/~jch/java/benchmarks.html

D.4.3 文章
[6] “Make Java fast:Optimize! How to get the greatest performanceout of your code through low-level optimizations in Java”(让Java更快:优化!若何通过在Java中的初级优化,使代码施展最超卓的性能).作者:Doug Bell.网址:
http://www.javaworld.com/javaworld/jw-04-1997/jw-04-optimize.html
(含一个全面的性能评测程序片,有细致注释)
[7] “Java Optimization Resources”(Java优化资源)
http://www.cs.cmu.edu/~jch/java/resources.html
[8] “Optimizing Java for Speed”(优化Java,提高速度):
http://www.cs.cmu.edu/~jch/java/speed.html
[9] “An Empirical Study of FORTRAN Programs”(FORTRAN程序实战解析).作者:Donald Knuth.1971年出版.第1卷,p.105-33,“软件——实践和操练”.
[10] “Building High-Performance Applications and Servers in Java:An Experiential Study”.作者:Jimmy Nguyen,Michael Fraenkel,RichardRedpath,Binh Q. Nguyen以及Sandeep K. Singhal.IBM T.J. Watson ResearchCenter,IBM Software Solutions.
http://www.ibm.com/java/education/javahipr.html

D.4.4 Java专业书籍
[11] 《Advanced Java,Idioms,Pitfalls,Styles, and Programming Tips》.作者:Chris Laffra.Prentice Hall 1997年出版(Java 1.0).第11章第20小节.

D.4.5 普通书籍
[12] 《Data Structures and C Programs》(数据构造和C程序).作者:J.Van Wyk.Addison-Wesly 1998年出版.
[13] 《Writing Efficient Programs》(编写有效的程序).作者:Jon Bentley.Prentice Hall 1982年出版.分外参考p.110和p.145-151.
[14] 《More Programming Pearls》(编程拾贝第二版).作者:JonBentley.“Association for Computing Machinery”,1998年2月.
[15] 《Programming Pearls》(编程拾贝).作者:Jone Bentley.Addison-Wesley 1989年出版.第2部份夸大了通例的性能改进问题. [16] 《Code Complete:A Practical Handbook of Software Construction》(完好代码索引:实用软件开辟手册).作者:Steve McConnell.Microsoft出版社1993年出版,第9章.
[17] 《Object-Oriented System Development》(面向对象系统的开辟).作者:Champeaux,Lea和Faure.第25章.
[18] 《The Art of Programming》(编程艺术).作者:Donald Knuth.第1卷“基本算法第3版”;第3卷“排序和搜索第2版”.Addison-Wesley出版.这是有关程序算法的一本百科全书.
[19] 《Algorithms in C:Fundammentals,Data Structures, Sorting,Searching》(C算法:底子、数据构造、排序、搜索)第3版.作者:RobertSedgewick.Addison-Wesley 1997年出版.作者是Knuth的学生.这是专门谈论几种语言的七个版本之一.对算法举行了深化浅出的注释.


  以上是“java的性能[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • 利用Javascript实现网页水印(非图片水印)
  • Java开辟环境的搭建
  • Ubuntu java安装与配置
  • 办理Ubuntu 10.04 Firefox3.6 Java浏览器插件不工作的问
  • Ubuntu重装后Java环境的设置
  • Sun Java进入Ubuntu 10.10软件中央
  • Ubuntu 10.10配置Java开辟环境
  • 在Ubuntu 10.10中配置Java环境变量的办法
  • Ubuntu下Java环境的搭建
  • Ubuntu 10.04 下安装 Java, JRE
  • Ubuntu 10.04下的搭建SUN JAVA开辟环境
  • Ubuntu 12.04安装java7
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .