工程中有段代码是对属性值做压缩的代码,实现的功能是:例如pid1:vid11;pid1:vid12;pid2:vid2,压缩后为pid1:vid11,vid12;pid2:vid2
原先代码如下:
public static String compressPropertyString(String prop) {
Map<Integer, List<Integer>> map = propString2map(prop);
StringBuilder sb = new StringBuilder();
for (Integer pid : map.keySet()) {
List<Integer> vals = map.get(pid);
sb.append(pid).append(psubSp);
int i = 0;
for (Integer vid : vals) {
if (i > 0) {
sb.append(parrSp);
}
sb.append(vid);
++i;
}
sb.append(pmainSp);
}
return sb.toString();
}
public static Map<Integer, List<Integer>> propString2map(String properties) {
Map<Integer, List<Integer>> map = new LinkedHashMap<Integer, List<Integer>>();
if (StringUtil.isNotBlank(properties)) {
String[] pairs = StringUtil.split(properties, pmainSp);
if (null != pairs) {
for (String pair : pairs) {
String pv[] = StringUtil.split(pair, psubSp);
Integer pid = new Integer(pv[0]);
String vstr = pv[1];
String[] vidarr = StringUtil.split(vstr, parrSp);
for (String vidstr : vidarr) {
Integer vid = new Integer(vidstr);
List<Integer> vids = map.get(pid);
if (null == vids) {
vids = new ArrayList<Integer>();
map.put(pid, vids);
}
if (!vids.contains(vid)) {
vids.add(vid);
}
}
}
}
}
return map;
}
原先代码中有一个方法propString2map(),次方法是将属性串解析成Map<Integer, List<Integer>>,次方法就直接调用了原有的这个方法,这段话压缩代码就很简单了,直接根据解析出来的Map拼装成字符串就ok了。
但是作者没有考虑propString2map()方法有一个处理是将里面的值都转换成了int,然后压缩时又转换成String。这么一个来回转换,完全是没有必要的。
所以对此方法进行了重构,代码如下:
public static String compressPropertyString(String prop) {
if(StringUtil.isBlank(prop)) return prop;
StringBuilder sb = new StringBuilder(prop.length());
String[] ps = StringUtil.split(prop,pmainSp);
if(ps == null) return prop;
Map<String,String> tmpMap = new LinkedHashMap<String,String>();
for(String pss : ps) {
String pv[] = StringUtil.split(pss,":");
if(tmpMap.containsKey(pv[0])) {
tmpMap.put(pv[0], tmpMap.get(pv[0]) +parrSp+ pv[1]);
}else {
tmpMap.put(pv[0], pv[1]);
}
}
for(String key: tmpMap.keySet()) {
sb.append(key).append(psubSp).append(tmpMap.get(key)).append(pmainSp);
}
return sb.toString();
}
执行测试结果如下:
public static void main(String args[] ) {
String s = "111:231;222:423;333:412;444:7523;111:610;111:868;444:852;555:123;666:513";
long start = System.currentTimeMillis();
String ss = null;
for(int i=0; i<1000000; i++) {
ss = PropertyUtils.compressPropertyString(s);
}
System.out.println(ss+" cost:"+(System.currentTimeMillis()-start));
}
优化前:
111:231,610,868;222:423;333:412;444:7523,852;555:123;666:513; cost:11043
优化后:
111:231,610,868;222:423;333:412;444:7523,852;555:123;666:513; cost:5953
可以看到,优化前后执行时间相差一半。
这个优化点,对于性能要求不高的应用来说没有必要。
对性能要求较高的应用,在写代码时就需要考虑,用到某个功能时,是直接使用已经实现的功能,还是自己重新实现一遍更高效的代码。