性能优化——安利十个Java小技巧
分类:技术社区 发布时间:2017/3/22 0:00:00

    在日常java编程过程中所用到的优化项和对比demo内容做了一下整理汇总,包含前后对比的实例,力求能方便大家看得懂、记得住,也希望对于其他语言有些许借鉴作用。内容如下:

  (1)for循环优化:在for循环中减少size()系统调用的时间开销。

  原始程序:
  for(int   i=0;i<list.size();i++){
  //TODO something
  }

  修正后:
  for(int   count=0,size=list.size();count<size;count++){
  //TODO something
  }


  (2)数据库查询:如果有些数据要经常要从数据库中读取,同时这些数据又不经常变化,这些数据就可以在系统中缓存起来,使用时直接读取缓存,而不用频繁的访问数据库读取数据,可以将原有O(n)复杂度将为O(1)。

  原始程序:
  for(Integer someId: IdList){
  Object object = DbService.query(someId);
  //TODO something
  }

  优化后:
  List<Object>   objList = DbService.queryByIdList(IdList);
  for(Object object: objList){
      //TODO something
  }

  

(3)异常信息:程序出现Exception情况下的错误信息栈通常很多,对开发人员查找问题比较方便,可以通过如下方式减少信息的输出:

  原始程序:
  try{}
  catch(Exception e){
      //打印完整错误栈信息
      logger.error(“Some Exception: ”, e);
  }
 
  优化后:
  try{}
  catch(Exception e){
      //仅打印异常类及原因信息
      logger.error("Some  Exception:"
      + e.getCause().getClass() +  "," + e.getCause().getMessage());
  }

 (4)数值比较:Integer或者Long值类型的对比时,可以采用自带的intValue()的方法转化为int类型进行数值得比较,不可直接用等于(= =)进行数值比较,String字符串的对比采用OneString.equal(OtherString)的方式进行内容是否相同的比较操作。

  

(5)字符串判空:采用equals()方法比length()方法开销大而且效率低,尤其是多重循环的情况下:

  原始程序:
  public boolean isEmpty(String str){
              return str.equals("");      
  }

  优化后:
  public boolean isEmpty(String str){
              return str.length()==0;    
  }

  

(6)Map遍历:遍历Map类型的数据,采用entrySet方式替换keySet方式,因为keySet其实是遍历了2次,一次是转为iterator,再一次是从hashmap中取出key所对于的value。而entryset只是遍历了第一次,他把key和value都放到了entry中,运行效率明显提升。

  原始代码:
  Map m = new HashMap();
  Iterator it = m.keySet().iterator();
  Object key = it.next();
  Object v = m.get(key);

  优化后:
  Map m = new HashMap();
  Set set =   m.entrySet();          
  Object   keyValuePair = it.next();

  

(7)多重布尔值判断:避免使用Boolean型的数组,使用BitSet,在多重判断中使用比较广泛。

  原始代码:
  boolean[] b = new   boolean[]{true, false, false};

  优化后:
  BitSet bs = new   BitSet(3); //初始长度为3的Set,默认全为false
  bs.set(0);//设置index为0的元素为true
  bs.get(2);//获取index为2的元素布尔值

 (8)字符串拼接:在字符串拼接的情况下,使用StringBuffer代替String类:

  原始代码:
  String result = "";
  for (int i = 0; i < 20;   i++){
      result +=   getNextString();                        
  }

  优化后:
  String result = "";
  StringBuffer   buffer = new StringBuffer();
  for (int i = 0; i < 20; i++)   {
         buffer.append(getNextString());              
  }
  result = buffer.toString();

  

(9)逻辑短路:用逻辑与或(||,&&)操作替换按位与或(|,&)操作,逻辑与或的符号只要经过第一个条件就能判断整个条件的真假,那么就没有必要对其后的逐个条件进行判断,即所谓的短路处理。按位与或的符号经过第一个条件就能判断整个条件的真假,还要对其后的所有条件进行判断,最后才所有的结果结合起来判断是真还是假。

  原始代码:
  if(sValue.equals("true")   | sValue.equals("false")){
                     System.out.println("valid boolean");
  }

  优化后:
  if(sValue.equals("true")   || sValue.equals("false")){
                     System.out.println("valid boolean");
  }

  

(10)数组拷贝:对于数组的循环拷贝处理可以调用System.arraycopy()完成处理,因为这个方法会调用JNI(Java Native Interface),即所在平台原生接口,处理大量数据的情况下效率较for循环或者调用强制类型转换的clone()方法更快。

  原始代码:
  int length = array.length;
  int[] copy = new int [length];
  for(int i=0;i<length;i++){
         copy [i] = array[i];         
  }
  return copy;

  优化后:
  final int ZERO = 0;
  int length = array.length;
  int[] copy = new int [length];
  System.arraycopy(array,   ZERO, copy, ZERO, length);
  return copy;

体验创新云技术带来核心业务效率显著提升
立即预约,加速企业数字化转型进程
Copyright ⓒ 2022 苏州博纳讯动软件有限公司 国徽 苏ICP备13004761号 法律声明及隐私政策