记一次老代码优化2

记一次老代码优化2


又发现了一个问题

上次的优化结果:

  • 老版本的转换方法用了204ms
  • 每次去查数据库因为要多次连接数据库进行查询操作,需要531ms
  • 而使用了缓存的方法,第一次我们还没有加载缓存,需要500ms,而第二次直接在缓存中读取,24ms,只用了之前方法的1/10。

让我们看一下上次优化的版本:


<code>public static String ospInOutParmConvert2(String str) {
Matcher m=p1.matcher(str);
String strTmp = "";
String strTmp1= "";
String nkKey = "";
String camelKey = "";
final Map<string> unSaveKeys = Maps.newHashMap();
while(m.find()){
strTmp = m.group();
nkKey = strTmp.replace("\"", "").replace(":", "");
camelKey = nkCamelKeyCacheService.getCamelKeyByNKKey(nkKey);
if (StringUtils.isNotBlank(camelKey)) {
str = str.replace(nkKey, camelKey);
continue;
} else {
camelKey = nkKey.toLowerCase();
str = str.replace(strTmp, strTmp.toLowerCase());

if (StringUtil.isNotEmpty(strTmp) && strTmp != "null") {
strTmp1= strTmp.toLowerCase();
if (strTmp1.indexOf("_") > 0) {
String[] strTmp1s = strTmp1.split("_");
for(int i=0; i<strtmp1s.length-1> int subInt = strTmp1.indexOf("_");
camelKey = camelKey.replace(strTmp1.substring(subInt,subInt + 2),strTmp1.substring(subInt + 1, subInt + 2).toUpperCase());
if(strTmp1s.length>1){
strTmp1 = strTmp1.substring(subInt+1);
}
}
str = str.replace(nkKey, camelKey);
}
unSaveKeys.put(nkKey, camelKey);
}
}
}
if (unSaveKeys.size() > 0) {
new Thread(new Runnable() {
@Override
public void run() {
LocalJDBCUtil.addNkCamelKeys(unSaveKeys);
}
}).start();
}
return str;
}
/<strtmp1s.length-1>/<string>/<code>

这一版没有对之前的算法进行优化,以为之前写代码的是个大佬,算法上应该没什么瑕疵。今天闲来无事仔细看了一下,发现一个问题:

如果根据正则匹配到一个key,就进行转换。

问题是,如果json中有List,那么list中的每条数据的map中的key都是相同的,每个都进行一遍运算会浪费很多资源。


怎么优化

这个问题是进行了不必要的运算,我们要记住哪些key已经计算并替换过了,当再次匹配到这些key的时候,直接跳过。


<code>public static String ospInOutParmConvert(String str) {
Matcher m = p1.matcher(str);
String strTmp = "";//双引号+冒号的key
String strTmp1 = "";//转换为小写的双引号+冒号的key
String nkKey = "";//能开key
String camelKey = "";//驼峰key
final Map<string> unSaveKeys = Maps.newHashMap();
Set<string> finishKeys = Sets.newHashSet();
while (m.find()) {
strTmp = m.group();
nkKey = strTmp.replace("\"", "").replace(":", "");
camelKey = nkCamelKeyCacheService.getCamelKeyByNKKey(nkKey);
if (finishKeys.contains(nkKey)) {
continue;//这个key已经替换过,跳过
} else if (StringUtils.isNotBlank(camelKey)) {
str = str.replace("\"" + nkKey + "\"", "\"" + camelKey + "\"");
finishKeys.add(nkKey);
continue;
} else {
camelKey = nkKey.toLowerCase();//如果没有_,那么这里转成小写就处理完了
if (StringUtil.isNotEmpty(strTmp) && strTmp != "null") {
strTmp1 = strTmp.toLowerCase();
if (strTmp1.indexOf("_") > 0) {
String[] strTmp1s = strTmp1.split("_");
for (int i = 0; i < strTmp1s.length - 1; i++) {
int subInt = strTmp1.indexOf("_");
camelKey = camelKey.replace(strTmp1.substring(subInt, subInt + 2), strTmp1.substring(subInt + 1, subInt + 2).toUpperCase());
if (strTmp1s.length > 1) {
strTmp1 = strTmp1.substring(subInt + 1);
}
}
}

str = str.replace("\"" + nkKey + "\"", "\"" + camelKey + "\"");
finishKeys.add(nkKey);
unSaveKeys.put(nkKey, camelKey);
}
}
}
if (unSaveKeys.size() > 0) {
new Thread(new Runnable() {
@Override
public void run() {
LocalJDBCUtil.addNkCamelKeys(unSaveKeys);
}
}).start();
}
return str;
}
/<string>/<string>/<code>

在这一版本中我用了一个finishKeys的Set来存放已经转换过的key,在计算前判断这个key是不是包含在finishKeys中,如果包含,说明已经转换过,直接跳过。


测试

还是之前的测试用例。
不过这次新方法第二次跑完的时间是17ms!!!


分享到:


相關文章: