Java中的StringBuilder機能測試。本站提示廣大學習愛好者:(Java中的StringBuilder機能測試)文章只能為提供參考,不一定能成為您想要的結果。以下是Java中的StringBuilder機能測試正文
在看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-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自帶的辦法,外部完成了
* @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= 94ms 10次stringIndexOf= 56ms 10次KMPIndexOf= 76ms 10次allbuild= 5870ms 10次alltoArray= 137ms 10*3次,GC= 155ms 10次,一切總計耗時: 6388ms; 消耗:6007ms; 消耗比: 94.03569192235442% -------------------------- 30次bfIndexOf= 365ms 30次stringIndexOf= 222ms 30次KMPIndexOf= 295ms 30次allbuild= 16452ms 30次alltoArray= 395ms 30*3次,GC= 452ms 30次,一切總計耗時: 18184ms; 消耗:16850ms; 消耗比: 92.66388033435987% -------------------------- 50次bfIndexOf;總計耗時: 550ms 50次stringIndexOf;總計耗時: 335ms 50次KMPIndexOf;總計耗時: 450ms 50次allbuild= 26501ms 50次alltoArray= 637ms 50*3次,GC;總計耗時: 734ms 50次,一切總計耗時: 29211ms; 消耗:27142ms; 消耗比: 92.91705179555647% --------------------------
從中可以看出來,應用StringBuilder結構字符串,800萬*50次append年夜約消費了26秒。換算上去每秒鐘是1600萬次。。。
看來是須要寫一個專門計時的函數,原來Junit是有本身的統計的,然則樣本不太好做。
如斯看來,數據的預備,也就是測試用例的拔取很症結,能夠須要師長教師成並寫入到文本文件中。