一次對java代碼性能的優化

前言:因涉及數據庫的操作是單表並且用的mybatis自帶的api,因此優化從重構代碼開始(目標:從三秒優化到一秒,優化的是業務代碼)

一:對代碼進行分析(分析可優化項)

①:將代碼中字符串拼接由+號改爲append的方式(性能對比如下)

public static void main(String[] args) {
        StopWatch stopWatch = new StopWatch("測試String");
        stopWatch.start("a");
        String adress;
        adress = "江蘇省"+"大廟市"+"趟水縣"+"趙王鄉"+"小李村"+"李家莊"+"1002號";
        System.err.println("adress:"+adress);
        stopWatch.stop();

        stopWatch.start("b");
        String adress2;
        StringBuffer st = new StringBuffer();
        adress2 = st.append("江蘇省").append("大廟市").append("趟水縣").append("趙王鄉").append("小李村").append("李家莊").append("1002號").toString();
        System.err.println("adress2:"+adress2);
        stopWatch.stop();
        System.err.println(stopWatch.prettyPrint());
    }

在這裏插入圖片描述
②:數據量較小的情況下用foreach代替stream和for循環(數據量大的時候用stream有優勢)

public static void main(String[] args) {
        List<Map<String, Object>> maps = new ArrayList<>();
        for (int i = 0; i < 500; i++) {
            maps.add(new HashMap<String,Object>(){{
                put("IYPLX",0);
                put("key1"+new Random().nextInt(1000),"張"+new Random().nextInt(1000));
            }});
            maps.add(new HashMap<String,Object>(){{
                put("IYPLX",1);
                put("key1"+new Random().nextInt(1000),"李"+new Random().nextInt(1000));
            }});
        }

        StopWatch stopWatch = new StopWatch();
        stopWatch.start("a");
        Map<String, Object> hashMap = new HashMap<>();
        List<Map<String, Object>> list11 = new ArrayList<>();
        List<Map<String, Object>> list22 = new ArrayList<>();
        for (Map<String, Object> map:maps) {
            if(map.get("IYPLX").equals(0)){
                list11.add(map);
            }
            if(map.get("IYPLX").equals(1)){
                list22.add(map);
            }
        }
        hashMap.put("XYCF",list11);
        hashMap.put("ZYCF",list22);
        System.err.println("list分組:"+hashMap.toString());
        stopWatch.stop();


        stopWatch.start("b");
        Map<String, Object> hashMap2 = new HashMap<>();
        Map<Object, List<Map<String, Object>>> iyplx = maps.stream().collect(Collectors.groupingBy(map -> map.get("IYPLX")));
        hashMap2.put("XYCF",iyplx.get(0));
        hashMap2.put("ZYCF",iyplx.get(1));
        System.err.println("java8分組:"+hashMap2.toString());
        stopWatch.stop();

        System.err.println(stopWatch.prettyPrint());

    }

在這裏插入圖片描述
③:對象轉化爲map的工具優化(通過分析性能排序從小到大 convert2Map->convertBean->PO2Map)

 public static void main(String[] args) throws Exception {
        MzzdPo1 mzzdPo1 = new MzzdPo1();
        mzzdPo1.setCBM("222");
        mzzdPo1.setCCS("11");
        mzzdPo1.setCDH("123");
        mzzdPo1.setCGG("23/s");
        mzzdPo1.setCKC("44");
        mzzdPo1.setCLS("55");
        mzzdPo1.setCNL("34");
        mzzdPo1.setCXM("zhan");
        StopWatch stopWatch = new StopWatch("測試");
        stopWatch.start("轉換map1");
        Map<String, Object> map1 = convertBean(mzzdPo1);
        stopWatch.stop();
        stopWatch.start("轉換map2");
        Map<String, Object> map2 = PO2Map(mzzdPo1);
        stopWatch.stop();
        stopWatch.start("轉換map3");
        Map<String, Object> map3 = convert2Map(mzzdPo1);
        stopWatch.stop();

        System.err.println("map1"+map1.toString());
        System.err.println("map2"+map2.toString());
        System.err.println("map3"+map3.toString());
        System.err.println(stopWatch.prettyPrint());
    }

    /**012530700 (3)*/
    public static Map<String, Object> PO2Map(Object o) throws Exception{
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] fields = null;
        String clzName = o.getClass().getSimpleName();
        log.info("類:"+o.getClass().getName());
        fields = o.getClass().getDeclaredFields();
        log.info("***"+clzName+"轉map開始****");
        for (Field field : fields) {
            field.setAccessible(true);
            String proName = field.getName();
            Object proValue = field.get(o);
            map.put(proName.toUpperCase(), proValue);
            log.info("key:"+proName+"value:"+proValue);
        }
        log.info("***"+clzName+"轉map結束****");
        return map;
    }

    /** 000054800  (1)*/
    private static <T>  Map<String, Object> convert2Map(T t) {
        Map<String, Object> result = new HashMap<String, Object>();
        Method[] methods = t.getClass().getMethods();
        try {
            for (Method method : methods) {
                Class<?>[] paramClass = method.getParameterTypes();
                if (paramClass.length > 0) { // 如果方法帶參數,則跳過
                    continue;
                }
                String methodName = method.getName();
                if (methodName.startsWith("get")) {
                    Object value = method.invoke(t);
                    result.put(methodName.substring(3,methodName.length()), value);
                }
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        return result;

    }


    /**009706100 (2)*/
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Map convertBean(Object bean)
            throws IntrospectionException, IllegalAccessException, InvocationTargetException {
        Class type = bean.getClass();
        Map returnMap = new HashMap();
        BeanInfo beanInfo = Introspector.getBeanInfo(type);
        PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();
        for (int i = 0; i< propertyDescriptors.length; i++) {
            PropertyDescriptor descriptor = propertyDescriptors[i];
            String propertyName = descriptor.getName();
            if (!propertyName.equals("class")) {
                Method readMethod = descriptor.getReadMethod();
                Object result = readMethod.invoke(bean, new Object[0]);
                if (result != null) {
                    returnMap.put(propertyName, result);
                } else {
                    returnMap.put(propertyName, "");
                }
            }
        }
        return returnMap;
    }

在這裏插入圖片描述
④:循環中創建對象由new改爲clone

public static void main(String[] args) {
        StopWatch stopWatch = new StopWatch("測試對象");
        stopWatch.start("a");
        List<Object> objects = new ArrayList<>();
        for (int i = 0; i <50; i++) {
            MzzdPo mzzdPo = new MzzdPo();
            mzzdPo.setId(i+"");
            mzzdPo.setName("張"+i);
            objects.add(mzzdPo);
        }
        System.err.println(objects.toString());
        stopWatch.stop();

        stopWatch.start("b");
        List<Object> objects2= new ArrayList<>();
        for (int i = 0; i <50; i++) {
            MzzdPo mzzdPo = MzzdPo.getInstance();
            mzzdPo.setId(i+"");
            mzzdPo.setName("張"+i);
            objects2.add(mzzdPo);
        }
        System.err.println(objects2.toString());
        stopWatch.stop();
        System.err.println(stopWatch.prettyPrint());
    }

MzzdPo 的對象要實現Cloneable接口

@Slf4j
@Data
public class MzzdPo implements Serializable,Cloneable {

    private String id;
    private String name;
    private String age;

    private static MzzdPo mzzdPo = new MzzdPo();

    public static MzzdPo getInstance() {
        try {
            return (MzzdPo)mzzdPo.clone();
        }catch (Exception e){
            log.error("clone 創建對象失敗,走的是new");
        }
        return new MzzdPo();
    }
}

在這裏插入圖片描述
⑤:總結:經過上面的四個方面優化,將代碼的性能由3秒優化到1秒,當然其他方面也可優化,根據實際情況去具體對待吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章