記一次老代碼優化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!!!


分享到:


相關文章: