上周沒事掃掃系統原來的代碼,突然發現這樣一段代碼:
if(log.isInfoEnable()){ log.info("ID"+userID+"pwd"+userPwd);}因為之前寫的日志類都是公司內部自己的日志類,對log4j用的并不多。當時看了這段代碼覺得很奇怪,代碼意思我是明白的,log本身就可以根據打印權限,判斷當前是否打印呀,為什么專門要加上這樣一條判斷呢?后來查了一下,發現是由于性能方面考慮的。
如果直接寫入這樣一段話
log.info("ID"+userID+"pwd"+userPwd);當打印等級為“info”之上時,系統并不會智能的跳過這句話,而是會進這句話的內部,那么進去之前第一件事,必定就是計算參數。那么這里就會拼接字符串了。
一般來說,日志的打印等級越低,打印的內容就越詳細(越趨于調試和跟蹤代碼),這時出現字符串拼接或者參數計算的東西就會越來越多,也就越耗費性能。此時如果我們設定當前的打印等級非常高,如ERROR等級,那么debug和info 級別的日志就不會打印,但是由于debug和info的打印語句非常多,組裝參數所耗費的性能也就非常大,所以我們這時候把判斷能否打印的語句放在外邊先進行判斷,雖然乍一看會覺得多此一舉,其實當debug和info的日志越多時,越能節約無謂的性能開銷。
很多網上很多人說這里不能為了代碼的易讀性而使用封裝,因為在調用封裝的方法時,其實已經開始計算參數了,反而顯得很可笑,如下:
public void info(String msg)//當前msg其實已經是拼接后的字符串了{ if(log.isInfoEnable()) { log.info("ID"+userID+"pwd"+userPwd); }}總結后的反思
1:很多人覺得,不封裝就會破壞代碼的易讀性,很難看,如果封裝了,又會起到反效果,所以壓根就不要節約這點性能好了,將時間和精力放置在數據庫連接查詢,數據加載排序等等這些更耗費性能的事情上,其實我也是贊同的,我覺得做性能優化就要一層層的做,沒必要從一開始就扣住所有細節,當然遵守一定的編碼制度是很好的。但是倘若一開始就從所有 細節著手,反而會影響其它重要的大的優化點。
2:對于這種寫法上我個人想了一下覺得如下的寫法既能保證代碼的可讀性,也能體現出這種判斷的性能優勢,但是會多出一個創建數組的性能開銷
1 public void info(String... args)//使用可變參數 2 { 3 if(log.isInfoEnabled()) 4 { 5 StringBuilder sb=new StringBuilder(); 6 for (int i = 0; i < args.length; i++) 7 { 8 sb.append(args[i]); 9 }10 log.info(sb.toString());11 }12 }13 }新聞熱點
疑難解答