前言:因涉及数据库的操作是单表并且用的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秒,当然其他方面也可优化,根据实际情况去具体对待吧