亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中的StringBuilder性能測試

 更新時(shí)間:2014年09月04日 09:47:28   投稿:junjie  
這篇文章主要介紹了Java中的StringBuilder性能測試,本文包含測試代碼和測試結(jié)果,最后得出結(jié)論,需要的朋友可以參考下

在看KMP算法時(shí),想要簡單的統(tǒng)計(jì)一下執(zhí)行時(shí)間和性能。

得出的結(jié)論是: Java的String的indexOf方法性能最好,其次是KMP算法,其次是傳統(tǒng)的BF算法,當(dāng)然,對比有點(diǎn)牽強(qiáng),SUN的算法也使用Java來實(shí)現(xiàn)、用的看著不像是KMP,還需要詳細(xì)研究一下。

測試代碼如下所示:

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. 構(gòu)造字符串的損耗
			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+";耗時(shí): "+timeoutBF+"ms");
			//System.out.println("indexString="+indexString+";耗時(shí): "+timeoutString+"ms");
			if(indexBF == indexString && indexKMP == indexString){
				//System.out.println("!!!!對比相等。");
			} else {
				throw new RuntimeException("對比出錯(cuò).");
			}
			
			//
			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+"次,所有總計(jì)耗時(shí): "+(allTime)+"ms; 損耗:" + lossTime +"ms; 損耗比: " +((0.0+lossTime)/allTime * 100)+"%");
				System.out.println("--------------------------");
			}
			
		}
		//
		System.out.println(times+"次bfIndexOf;總計(jì)耗時(shí): "+allBF+"ms");
		System.out.println(times+"次stringIndexOf;總計(jì)耗時(shí): "+allString+"ms");
		System.out.println(times+"次KMPIndexOf;總計(jì)耗時(shí): "+allKMP+"ms");
		System.out.println(times+"次allbuild= "+allbuild+"ms");
		System.out.println(times+"次alltoArray= "+alltoArray+"ms");
		System.out.println(times+"*3次,GC;總計(jì)耗時(shí): "+allGC+"ms");
		long end = System.currentTimeMillis();
		long allTime = end-start;
		long lossTime = allTime - (allBF+allString+allKMP+allGC);
		System.out.println(times+"次,所有總計(jì)耗時(shí): "+(allTime)+"ms; 損耗:" + lossTime +"ms; 損耗比: " +((0.0+lossTime)/allTime * 100)+"%");
		System.out.println("--------------------------");
		
	}
	
	//
	
	
	// 構(gòu)建字符

	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-2
			int 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自帶的方法,內(nèi)部實(shí)現(xiàn)了
	 * @param all
	 * @param sub
	 * @return
	 */
	public static int stringIndexOf(String all, String sub){
		// 防御式編程
		if(null == all || null== sub){
			return -1;
		}
		// 調(diào)用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下標(biāo)開始對比
			int j = 0;
			while (j < lenSub) {
				//
				char all_i = all.charAt(i);
				char sub_j = sub.charAt(j);
				if(all_i == sub_j){
					// 相等則繼續(xù)對比下一個(gè)字符
					i++;
					j++; // 這個(gè)增長很重要
				} else {
					// 否則跳出內(nèi)層循環(huán)
					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函數(shù)值 
   * 
   * @param t 
   *      字符串 
   * @return next函數(shù)值 
   */ 
  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 若匹配成功,返回下標(biāo),否則返回-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; // 返回模式串在主串中的頭下標(biāo) 
  } 
}

測試的一個(gè)結(jié)果如下所示:

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

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

如此看來,數(shù)據(jù)的準(zhǔn)備,也就是測試用例的選取很關(guān)鍵,可能需要先生成并寫入到文本文件中。

相關(guān)文章

  • MyBatis攔截器實(shí)現(xiàn)分頁功能實(shí)例

    MyBatis攔截器實(shí)現(xiàn)分頁功能實(shí)例

    本篇文章主要介紹了MyBatis攔截器實(shí)現(xiàn)分頁功能實(shí)例,這里整理了詳細(xì)的代碼,有需要的小伙伴可以參考下。
    2017-04-04
  • Java判斷字符串是不是數(shù)字過程解析

    Java判斷字符串是不是數(shù)字過程解析

    這篇文章主要介紹了Java判斷字符串是不是數(shù)字過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java 反轉(zhuǎn)帶頭結(jié)點(diǎn)的單鏈表并顯示輸出的實(shí)現(xiàn)過程

    Java 反轉(zhuǎn)帶頭結(jié)點(diǎn)的單鏈表并顯示輸出的實(shí)現(xiàn)過程

    這篇文章主要介紹了Java 反轉(zhuǎn)帶頭結(jié)點(diǎn)的單鏈表并顯示輸出,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • 徹底搞明白Spring中的自動(dòng)裝配和Autowired注解的使用

    徹底搞明白Spring中的自動(dòng)裝配和Autowired注解的使用

    這篇文章主要介紹了徹底搞明白Spring中的自動(dòng)裝配和Autowired注解的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03
  • Java @RequestMapping注解功能使用詳解

    Java @RequestMapping注解功能使用詳解

    通過@RequestMapping注解可以定義不同的處理器映射規(guī)則,下面這篇文章主要給大家介紹了關(guān)于SpringMVC中@RequestMapping注解用法的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • 詳解Spring如何整合Mybatis

    詳解Spring如何整合Mybatis

    今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著Spring如何整合Mybatis展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • SpringBoot中攔截器和動(dòng)態(tài)代理的區(qū)別詳解

    SpringBoot中攔截器和動(dòng)態(tài)代理的區(qū)別詳解

    在?Spring?Boot?中,攔截器和動(dòng)態(tài)代理都是用來實(shí)現(xiàn)功能增強(qiáng)的,所以在很多時(shí)候,有人會認(rèn)為攔截器的底層是通過動(dòng)態(tài)代理實(shí)現(xiàn)的,所以本文就來盤點(diǎn)一下他們兩的區(qū)別,以及攔截器的底層實(shí)現(xiàn)吧
    2023-09-09
  • SpringBoot全局異常處理方式

    SpringBoot全局異常處理方式

    這篇文章主要介紹了SpringBoot全局異常處理方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java程序中實(shí)現(xiàn)調(diào)用Python腳本的方法詳解

    Java程序中實(shí)現(xiàn)調(diào)用Python腳本的方法詳解

    這篇文章主要介紹了Java程序中實(shí)現(xiàn)調(diào)用Python腳本的方法,結(jié)合實(shí)例形式分析了eclipse環(huán)境中使用Java調(diào)用Python腳本的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2018-03-03
  • 使用Spring啟動(dòng)時(shí)運(yùn)行自定義業(yè)務(wù)

    使用Spring啟動(dòng)時(shí)運(yùn)行自定義業(yè)務(wù)

    這篇文章主要介紹了使用Spring啟動(dòng)時(shí)運(yùn)行自定義業(yè)務(wù)的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評論