JAVA提高代码效率的方法课件_第1页
JAVA提高代码效率的方法课件_第2页
JAVA提高代码效率的方法课件_第3页
JAVA提高代码效率的方法课件_第4页
JAVA提高代码效率的方法课件_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、提高代码效率的方法第1页,共29页。优化循环体循环是比较重复运行的地方,如果循环次数很大,循环体内不好的代码对效率的影响就会被放大而变的突出。让我们看看下面的代码片:.Vector vect = new Vector(1000);.for( int i=0; ivect.size(); i+).for循环部分改写成:int size = vect.size(); for( int i=0; i size; i+).如果size=1000,就可以减少1000次size()的系统调用开销,避免了循环体重复调用。未优化耗时:780309优化后耗时:624430第2页,共29页。少用NEW初始化一个实

2、例尽量少用new来初始化一个类的实例,当一个对象是用new进行初始化时,其构造函数链的所有构造函数都被调用到,所以new操作符是很消耗系统资源的,new一个对象耗时往往是局部变量赋值耗时的上千倍。同时,当生成对象后,系统还要花时间进行垃圾回收和处理。当new创建对象不可避免时,注意避免多次的使用new初始化一个对象。尽量在使用时再创建该对象。如:NewObject object = new NewObject();int value;if( i0 )value =object.getValue();修改为:int value;if ( i 0 )NewObject object = new N

3、ewObject();value =object.getValue(); 另外,应该尽量重复使用一个对象,而不是声明新的同类对象。一个重用对象的方法是改变对象的值,如可以通过setValue之类的方法改变对象的变量达到重用的目的。第3页,共29页。在Java中,一切都是对象,如果有方法(Method)调用,处理器先要检查该方法是属于哪个对象,该对象是否有效,对象属于什么类型,然后选择合适的方法并调用。 可以减少方法的调用,同样一个方法:int i = 0;.CallMethod(i); public void CallMethod(int i )if( i =0 )return;. / 其他处

4、理可修改为:int i = 0;.if( i =0 )CallMethod(i);不影响可读性等情况下,可以把几个小的方法合成一个大的方法。另外,在方法前加上final,private关键字有利于编译器的优化选择合适的方法调用第4页,共29页。尽量使用局部变量 调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢。另外,依赖于具体的编译器/JVM,局部变量还可能得到进一步优化。 例子:public class USER private int _sum; private static int _

5、staticSum; void getSum (int values) for (int i=0; i values.length; i+) _sum += valuesi; / violation. 更正: 如果可能,请使用局部变量作为你经常访问的变量。你可以按下面的方法来修改getSum()方法: void getSum (int values) int sum = _sum; / temporary local variable. for (int i=0; i values.length; i+) sum += valuesi; _sum = sum; 第5页,共29页。STRING与

6、STRINGBUFFER的使用技巧1、字符串在JAVA中被广泛的使用,但是由于String 对象是不可改变的, 所以如果我们试图将两个String对象相加的时候,它实际的执行是产生一个中间对象StringBuffer,并调用它的append ()法来进行相加的,最后调用StringBufffer的toString()方法来返回一个String的对象,如果只是一般的相加差别不大,但是如果是在循环中,性能差距就较明显注:String s = “a” + “b” + “c”,实际上在编译后是String s=“abc”,执行时不存在相加问题 2、在字符串相加的时候,如果该字符串只有一个字符的话 如:

7、String str = s + “d”应该换作 string = s + d来执行。3、由于在创建一个StringBuffer对象时, StringBuffer的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,如果可以的话 ,在创建StringBuffer的时候应指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。第6页,共29页。返回STRING与STRINGBUFFER的使用技巧第7页,共29页。尽可能的使用Java自身提供的API用JAVA自身的Syste

8、m.arraycopy方法明显省时第8页,共29页。不要重复初始化变量 默认情况下,调用类的构造函数时, Java会把变量初始化成确定的值:所有的对象被设置成null,整数变量(byte、short、int、long)设置成0,float和double变量设置成0.0,逻辑值设置成false。当一个类从另一个类派生时,这一点尤其应该注意,因为用new关键词创建一个对象时,构造函数链中的所有构造函数都会被自动调用。第9页,共29页。避免不需要的造型操作 所有的类都是直接或者间接继承自Object。同样,所有的子类也都隐含的“等于”其父类。那么,由子类造型至父类的操作就是不必要的了。例子:clas

9、s UNC String _id = UNC;class Dog extends UNC void method () Dog dog = new Dog (); UNC animal = (UNC)dog; / not necessary. Object o = (Object)dog; / not necessary. 更正: class Dog extends UNC void method () Dog dog = new Dog(); UNC animal = dog; Object o = dog; 第10页,共29页。如果只是查找单个字符的话,用CHARAT()代替STARTSW

10、ITH() 用一个字符作为参数调用startsWith()也会工作的很好,但从性能角度上来看,调用charAt更好 例子:public class PCTS private void method(String s) if (s.startsWith(a) / violation / . 更正 将startsWith() 替换成charAt().public class PCTS private void method(String s) if (a = s.charAt(0) / . 第11页,共29页。不要在循环中调用SYNCHRONIZED(同步)方法 方法的同步需要消耗相当大的资源,在

11、一个循环中调用它绝对不是一个好主意。例子:import java.util.Vector;public class SYN public synchronized void method (Object o) private void test () for (int i = 0; i vector.size(); i+) method (vector.elementAt(i); / violation private Vector vector = new Vector (5, 5);第12页,共29页。不要在循环中调用SYNCHRONIZED(同步)方法 更正:不要在循环体中调用同步方法,

12、如果必须同步的话,推荐以下方式:import java.util.Vector;public class SYN public void method (Object o) private void test () synchronized/在一个同步块中执行非同步方法 for (int i = 0; i vector.size(); i+) method (vector.elementAt(i); private Vector vector = new Vector (5, 5);第13页,共29页。ORACLE的SQL语句尽量使用大写 在JAVA + ORACLE 的应用系统开发中,jav

13、a中内嵌的SQL语句尽量使用大写的形式,以减轻ORACLE解析器的解析负担。 第14页,共29页。减少I/O操作尽量减少I/O操作: 输入/输出(I/O)包括很多方面,我们知道,进行I/O操作是很消耗系统资源的。程序中应该尽量少用I/O操作。使用时可以注意: . 合理控制输出函数System.out.println()对于大多时候是有用的,特别是系统调试的时候,但也会产生大量的信息出现在控制台和日志上,同时输出时,有序列化和同步的过程,造成了开销。特别是在发行版中,要合理的控制输出,可以在项目开发时,设计好一个Debug的工具类,在该类中可以实现输出开关,输出的级别,根据不同的情况进行不同的输

14、出的控制。尽量使用缓存:读写内存要比读写硬盘上的文件要快很多,应尽可能使用缓冲,以便直接从内存中读取数据。尽可能使用带有Buffer的类代替没有Buffer的类,如可以用BufferedReader 代替Reader,用BufferedWriter代替Writer来进行处理I/O操作。同样可以用BufferedInputStream代替InputStream都可以获得性能的提高 第15页,共29页。即时关闭I/O流操作 Java 编程过程中,I/O流操作时务必小心,在使用完毕后,及时关闭以释放资源。因为对这些大对象的操作会造成系统大的开销,稍有不慎,会导致严重的后果。第16页,共29页。在FI

15、NALLY块中关闭STREAM程序中使用到的资源应当被释放,以避免资源泄漏。这最好在finally块中去做。不管程序执行的结果如何,finally块总是会执行的,以确保资源的正确关闭。例子:import java.io.*;public class CS public static void main (String args) CS cs = new CS (); cs.method (); public void method () try FileInputStream fis = new FileInputStream (CS.java); int count = 0; while (

16、fis.read () != -1) count+; System.out.println (count); fis.close (); catch (FileNotFoundException e1) catch (IOException e2) 更正:在最后一个catch后添加一个finally块第17页,共29页。对象使用完毕应手动置成NULL 由于JVM的有其自身的GC机制,不需要程序开发者的过多考虑,从一定程度上减轻了开发者负担,但同时也遗漏了隐患,过分的创建对象会消耗系统的大量内存,严重时会导致内存泄露,因此,保证过期对象的及时回收具有重要意义。JVM回收垃圾的条件是:对象不在被引

17、用;然而,JVM的GC并非十分的机智,即使对象满足了垃圾回收的条件也不一定会被立即回收。所以,建议我们在对象使用完毕,应手动置成null。 第18页,共29页。慎用异常 异常对性能不利。抛出异常首先要创建一个新的对象。Throwable接口的构造函数调用名为fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,VM就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。异常只能用于错误处理,不应该用来控制程序流程。 第19页,共29页。尽量不要在循环中使用 TRY CATCHTry catch()

18、如无特殊要求,应把其放置在最外层。 比如数据回滚第20页,共29页。集合类优化问题集合类在此Java编程中被广泛地使用,一个集合类就是将一组对象组装成一个对象Java的集合类框架由一些接口(如Collection、List、Set、Map)和一些为通用目的而实现的类(如Vector,ArrayList、Hashtable等等)组成,这些类里,有些提供了某种排序算法,有的提供了同步的方法,有如此多的集合类,在具体使用过程中,我们如何根据自己的需要选择合适的集合类,将对程序的性能产生很大的影响,下面将一些常用的类进行比较:Vector和ArrayList Vector和ArrayList在使用上非

19、常相似,都可用来表示一组数量可变的对象应用的集合,并且可以随机地访问其中的元素。它们的区别如下: 1、Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好.2、当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样ArrayList就有利于节约内存空间。Hashtable和HashMap 它们的性能方面的比较类似 Vector和ArrayList,比如Hasht

20、able的方法是同步的,而HashMap的不是。 当它们中的元素超过它的初始大小时,都会将它的容量翻倍。第21页,共29页。ArrayList和LinkedList 对于处理一列数据项,Java提供了两个类ArrayList和LinkedList,ArrayList的内部实现是基于内部数组Object,所以从概念上讲,它更象数组,但LinkedList的内部实现是基于一组连接的记录,所以,它更象一个链表结构,所以,它们在性能上有很大的差别。 (1)在ArrayList的前面或中间插入数据时,你必须将其后的所有数据相应的后移,这样必然要花费较多时间,所以,当你的操作是在一列数据的后面添加数据而不

21、是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能。 (2)访问链表中的某个元素时,就必须从链表的一端开始沿着连接方向一个一个元素地去查找,直到找到所需的元素为止,所以,当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。 注意:在Java集合框架中的大部分类的大小是可以随着元素个数的增加而相应的增加的,我们似乎不用关心它的初始大小,但如果我们考虑类的性能问题时,就一定要考虑尽可能地设置好集合对象的初始大小,这将大大提高代码的性能,比如,Hashtable缺省的初始大小为11,载入因子为0.75

22、,即如果其中的元素个数超过7个,它就必须增加大小并重新组织元素,所以,如果你知道在创建一个新的Hashtable对象时就知道元素的确切数目如为12,那么,就应将其初始大小设为12/0.75=16,这样,就可以避免重新组织内存并增加大小。(默认Vector ArrayList 10个大小,Hashtable 11,HashMap 16)集合类优化问题第22页,共29页。第23页,共29页。返回第24页,共29页。不用保存太多的信息在HTTPSESSION中很多时候,存储一些对象在HttpSession中是有必要的,可以加快系统的开发,如网上商店系统会把购物车信息保存在该用户的Session中,但

23、当存储大量的信息或是大的对象在会话中时,是有害的,特别是当系统中用户的访问量很大,对内存的需求就会很高。第25页,共29页。不用保存太多的信息在HTTPSESSION中清除SESSION:通常情况,当达到设定的超时时间时,同时有些Session没有了活动,服务器会释放这些没有活动的Session,. 不过这种情况下,特别是多用户并访时,系统内存要维护多个的无效Session。当用户退出时,应该手动释放,回收资源,实现如下:HttpSession theSession = request.getSession();/ 获取当前Sessionif(theSession != null)theSession.invalidate(); / 使该Session失效第26页,共29页。在JSP页面中关闭无用的会话一个常见的误解是以为session在有客户端访问时就被创建,然而事实是直到某server端程序调用HttpServletRequest.getSession(true)这样的语句时才被创建,注意如果JSP没有显示的使用 关闭session,则JSP文件在编译成Servlet时将会自动加上这样一条语句HttpSession session = HttpServletRequest.getSession(true);这也是JSP中隐含的session对象的来历。由于sessio

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论