15天的性能优化工作,5方面的调优经验

开心一笑

世界上最互相信任的两个人应该是初中老师和高中老师了。
初中老师:这个知识点到高中你们老师会讲的,你们现在不必要知道。
高中老师:这个知识点你们初中老师肯定讲过了,我就不讲了。
:你TM在逗我吗???

提出问题

性能优化时候,应该从哪几方面入手???

前言

前一段时间一直在做性能调优的工作,颇有收获。因此,简单的总结并分享下研究成果。性能调优很有趣但也是个无底洞,不可能在一篇文章全部阐述完。这里只是提供一个方向,以后碰到了知道可以从这些方面入手即可。具体如下:

性能调优

代码层面

for循环中不要利用 + 号去拼接字符串

在循环次数比较多的for循环中,我们也不要利用 + 号去拼接字符串。具体例子如下:

程序清单 1-1

@Test
public void test(){
    String str = "ay";
    for(int i=0;i<Integer.MAX_VALUE;i++){
         str = str + i;
    }
}

具体解决方法如下:

  • 根据具体的业务场景,使用 StringBuffer(线程安全)或者 StringBuilder(非线程安全)

  • 使用数组

      程序清单 1-1
    
      @Test
      public void test(){
          //第一种解决方法
          StringBuilder stringBuilder = new StringBuilder(Integer.MAX_VALUE);
          //第二种解决方法
          String[] strArray = new String[Integer.MAX_VALUE + 1];
          stringBuilder.append("ay");
          strArray[0] = "ay";
          for(int i=0;i<Integer.MAX_VALUE + 1;i++){
              stringBuilder.append("al");
              strArray[i + 1] = "al";
          }
          System.out.println(stringBuilder.toString());
          System.out.println(ArrayUtils.toString(strArray));
      }
    
设置容量参数提高系统性能

对于 StringBuffer(线程安全)或者 StringBuilder(非线程安全),都有相应的构造方法:

程序清单 1-1

public StringBuilder(int capacity) {
    super(capacity);
}

如果我们可以事先知道需要拼接的字符串长度,设置容量参数,防止 StringBuffer 在源码内部进行一系列复杂的内存复制操作,影响性能。

如上面的

StringBuilder stringBuilder = new StringBuilder(Integer.MAX_VALUE);
for循环建议写法
for (int i = 0, int length = list.size(); i < length; i++)
方法的返回值

返回List:

private List<PcsTaskDTO> sortDecisionAndBackTask(List<PcsTaskDTO> pcsTaskDTOList) throws Exception{
        if(CollectionUtils.isEmpty(pcsTaskDTOList)) return null;
}

解决方法:

private List<PcsTaskDTO> sortDecisionAndBackTask(List<PcsTaskDTO> pcsTaskDTOList) throws Exception{
        if(CollectionUtils.isEmpty(pcsTaskDTOList)) return Collections.EMPTY_LIST;
}

返回Set:

Collections.EMPTY_SET

返回Map:

Collections.EMPTY_MAP

返回Boolean:

Boolean.TRUE
不要再for循环中查询数据库

解决:

  • 根据业务场景,把for循环中的多次连接数据库查询,写到sql中去查询,既一次性查询出来
  • 根据业务场景,看是否可以利用缓存,提高查询效率
去掉System.out.println

代码部署到生产环境前,去掉全部System.out.println

四种数组复制方式的性能比较和抉择

数组copy有很多种方法,效率不一。我们先看下面具体实例:

程序清单 2-1	

/**
 * 测试4种数组复制效率比较
 * @author 阿毅
 * @date 2017/2/7.
 */
public class AyTest {

    private static final byte[] buffer = new byte[1024*10];
    static {
        for (int i = 0; i < buffer.length; i++) {
            buffer[i] = (byte) (i & 0xFF);
        }
    }
    private static long startTime;

    public static void main(String[] args) {
        startTime = System.nanoTime();
        byte[] newBuffer = new byte[buffer.length];
        for(int i=0;i<buffer.length;i++) {
            newBuffer[i] = buffer[i];
        }
        calcTime("forCopy");

        startTime = System.nanoTime();
        byte[] newBuffer2 = buffer.clone();
        calcTime("cloneCopy");

        startTime = System.nanoTime();
        byte[] newBuffer3 = Arrays.copyOf(buffer, buffer.length);
        calcTime("arraysCopyOf");

        startTime = System.nanoTime();
        byte[] newBuffer4 = new byte[buffer.length];
        System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
        calcTime("systemArraycopy");
    }

    private static void calcTime(String type) {
        long endTime = System.nanoTime();
        System.out.println(type + " cost " +(endTime-startTime)+ " nanosecond");
    }
}

运行结果:

forCopy cost 711576 nanosecond
cloneCopy cost 53490 nanosecond
arraysCopyOf cost 119946 nanosecond
systemArraycopy cost 39712 nanosecond

多运行几次,我们得出数组复制效率:

System.arraycopy > clone > Arrays.copyOf > for

评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿_毅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值