Java中的StringBuilder效能測試_java

來源:互聯網
上載者:User

在看KMP演算法時,想要簡單的統計一下執行時間和效能。

得出的結論是: Java的String的indexOf方法效能最好,其次是KMP演算法,其次是傳統的BF演算法,當然,對比有點牽強,SUN的演算法也使用Java來實現、用的看著不像是KMP,還需要詳細研究一下。

測試代碼如下所示:

package com.test.test.kmp;import java.util.Random;public class KMPTest {public static void main(String[] args) {test();}//public static void test() {//int allLen = 8000000;int subLen = 11;int charLen = 4;String cl = buildString(charLen);int times = 50;//testMatch(allLen, subLen, cl, times);}public static void testMatch(int allLen, int subLen, String cl, int times){int allBF = 0;int allString = 0;int allKMP = 0;int allGC = 0;int allbuild = 0;int alltoArray = 0;long start = System.currentTimeMillis();System.out.println("--------------------------");for (int i = 0; i < times; i++) {// 1. 構造字串的損耗long buildStart = System.currentTimeMillis();String sub = buildString(subLen, cl);String all = buildString(allLen, sub) +sub;long buildEnd = System.currentTimeMillis();allbuild += (buildEnd - buildStart);// 2. toCharArray的損耗long toArrayStart = System.currentTimeMillis();char[] allArray = all.toCharArray();char[] subArray = sub.toCharArray();long toArrayEnd = System.currentTimeMillis();alltoArray += (toArrayEnd - toArrayStart);//long startBF = System.currentTimeMillis();int indexBF = bfIndexOf(all, sub);long endBF = System.currentTimeMillis();//long timeoutBF = endBF - startBF;allBF += timeoutBF;System.gc();allGC += (System.currentTimeMillis() - endBF);//long startString = System.currentTimeMillis();int indexString = stringIndexOf(all, sub);long endString = System.currentTimeMillis();//long timeoutString = endString - startString;allString += timeoutString;System.gc();allGC += (System.currentTimeMillis() - endString);//long startKMP = System.currentTimeMillis();//int indexKMP = kmpIndexOf(all, sub);int indexKMP = KMP_Index(allArray, subArray);long endKMP = System.currentTimeMillis();//long timeoutKMP = endKMP - startKMP;allKMP += timeoutKMP;System.gc();allGC += (System.currentTimeMillis() - endKMP);////System.out.println("all="+all.substring(0,100)+" ......");//System.out.println("sub="+sub);////System.out.println("indexBF="+indexBF+";耗時: "+timeoutBF+"ms");//System.out.println("indexString="+indexString+";耗時: "+timeoutString+"ms");if(indexBF == indexString && indexKMP == indexString){//System.out.println("!!!!對比相等。");} else {throw new RuntimeException("對比出錯.");}//if(i % 20 == 10){System.out.println(i+"次bfIndexOf= "+allBF+"ms");System.out.println(i+"次stringIndexOf= "+allString+"ms");System.out.println(i+"次KMPIndexOf= "+allKMP+"ms");System.out.println(i+"次allbuild= "+allbuild+"ms");System.out.println(i+"次alltoArray= "+alltoArray+"ms");System.out.println(i+"*3次,GC= "+allGC+"ms");long end = System.currentTimeMillis();long allTime = end-start;long lossTime = allTime - (allBF+allString+allKMP+allGC);System.out.println(i+"次,所有總計耗時: "+(allTime)+"ms; 損耗:" + lossTime +"ms; 損耗比: " +((0.0+lossTime)/allTime * 100)+"%");System.out.println("--------------------------");}}//System.out.println(times+"次bfIndexOf;總計耗時: "+allBF+"ms");System.out.println(times+"次stringIndexOf;總計耗時: "+allString+"ms");System.out.println(times+"次KMPIndexOf;總計耗時: "+allKMP+"ms");System.out.println(times+"次allbuild= "+allbuild+"ms");System.out.println(times+"次alltoArray= "+alltoArray+"ms");System.out.println(times+"*3次,GC;總計耗時: "+allGC+"ms");long end = System.currentTimeMillis();long allTime = end-start;long lossTime = allTime - (allBF+allString+allKMP+allGC);System.out.println(times+"次,所有總計耗時: "+(allTime)+"ms; 損耗:" + lossTime +"ms; 損耗比: " +((0.0+lossTime)/allTime * 100)+"%");System.out.println("--------------------------");}//// 構建字元public static String buildString(int len){return buildString(len, null);}public static String buildString(int len, String sub){//final int TYPE_NUMBER = 0;final int TYPE_LOWERCASE = 1;final int TYPE_UPPERCASE = 2;//long seed = System.nanoTime();Random random = new Random(seed);////StringBuilder builder = new StringBuilder();for (int i = 0; i < len; i++) {//int type = random.nextInt(3);// 0-2int cvalue = 0;if(TYPE_NUMBER == type){cvalue = '0' + random.nextInt(10);// 0~(n-1)} else if(TYPE_LOWERCASE == type){cvalue = 'a' + random.nextInt(26);// 0~(n-1)} else if(TYPE_UPPERCASE == type){cvalue = 'A' + random.nextInt(26);// 0~(n-1)} else {throw new RuntimeException(Random.class.getName()+"#newxtInt(int);Wrong!");}////cvalue = 'A' + random.nextInt(26);// 0~(n-1)//char c = (char)cvalue;if(null != sub && sub.length() > 1){int index = random.nextInt(sub.length());c = sub.charAt(index);}//String s = String.valueOf(c);builder.append(c);//}//return builder.toString();}/** * Java內建的方法,內部實現了 * @param all * @param sub * @return */public static int stringIndexOf(String all, String sub){// 防禦式編程if(null == all || null== sub){return -1;}// 調用Java的String方法return all.indexOf(sub);}/** * BF演算法 * @param all * @param sub * @return */public static int bfIndexOf(String all, String sub){// 防禦式編程if(null == all || null== sub){return -1;}//int lenAll = all.length();int lenSub = sub.length();int i = 0;while (i < lenAll) {// 從i下標開始對比int j = 0;while (j < lenSub) {//char all_i = all.charAt(i);char sub_j = sub.charAt(j);if(all_i == sub_j){// 相等則繼續對比下一個字元i++;j++; // 這個增長很重要} else {// 否則跳出內層迴圈break;}}// 如果 j 增長到和 lenSub相等,則匹配成功if(lenSub == j){return i - lenSub;} else {i = 1+i - j; // 回溯 i}}//return -1;}/** * KMP 演算法 * @param all * @param sub * @return */public static int kmpIndexOf(String all, String sub){//char[] allArray = all.toCharArray(); char[] subArray = sub.toCharArray(); //return KMP_Index(allArray, subArray);}  /**    * 獲得字串的next函數值    *    * @param t    *      字串    * @return next函數值    */   public static int[] next(char[] t) {     int[] next = new int[t.length];     next[0] = -1;     int i = 0;     int j = -1;     while (i < t.length - 1) {       if (j == -1 || t[i] == t[j]) {         i++;         j++;         if (t[i] != t[j]) {           next[i] = j;         } else {           next[i] = next[j];         }       } else {         j = next[j];       }     }     return next;   }    /**    * KMP匹配字串    *    * @param allArray    *      主串    * @param subArray    *      模式串    * @return 若匹配成功,返回下標,否則返回-1    */ public static int KMP_Index(char[] allArray, char[] subArray) {     int[] next = next(subArray);     int i = 0;     int j = 0;     while (i <= allArray.length - 1 && j <= subArray.length - 1) {       if (j == -1 || allArray[i] == subArray[j]) {         i++;         j++;       } else {         j = next[j];       }     }     if (j < subArray.length) {       return -1;     } else       return i - subArray.length; // 返回模式串在主串中的頭下標   } }

測試的一個結果如下所示:

--------------------------10次bfIndexOf= 94ms10次stringIndexOf= 56ms10次KMPIndexOf= 76ms10次allbuild= 5870ms10次alltoArray= 137ms10*3次,GC= 155ms10次,所有總計耗時: 6388ms; 損耗:6007ms; 損耗比: 94.03569192235442%--------------------------30次bfIndexOf= 365ms30次stringIndexOf= 222ms30次KMPIndexOf= 295ms30次allbuild= 16452ms30次alltoArray= 395ms30*3次,GC= 452ms30次,所有總計耗時: 18184ms; 損耗:16850ms; 損耗比: 92.66388033435987%--------------------------50次bfIndexOf;總計耗時: 550ms50次stringIndexOf;總計耗時: 335ms50次KMPIndexOf;總計耗時: 450ms50次allbuild= 26501ms50次alltoArray= 637ms50*3次,GC;總計耗時: 734ms50次,所有總計耗時: 29211ms; 損耗:27142ms; 損耗比: 92.91705179555647%--------------------------

從中可以看出來,使用StringBuilder構造字串,800萬*50次append大約消耗了26秒。換算下來每秒鐘是1600萬次。。。
看來是需要寫一個專門計時的函數,本來Junit是有自己的統計的,但是樣本不太好做。

如此看來,資料的準備,也就是測試案例的選取很關鍵,可能需要先產生並寫入到文字檔中。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.