Java字符串分割性能比较
关于字符串的分割,我用jdk的split、apache的common的split、正则表达式、StringTokenizerr以及substring做了以下比较,比较的时间为纳秒,用一个字符串“192.168.20.121”作为示例,打印时间为:
- 使用jdk的split切分字符串
192 168 20 121 花费时间1086171 - 使用common的split切分字符串
192 168 20 121 花费时间9583620 - 使用StringTokenizer的切分字符串
192 168 20 121 花费时间184380 - 使用jdk的pattern切分字符串
192 168 20 121 花费时间222654 - 使用jdk的substring切分字符串
192 168 20 121 花费时间157562
虽然每次打印的时间不太相同,但是基本相差不大。通过以上分析得知使用substring和StringTokenizer的效率相对较高,其它相对较差。
为什么StringTokenizer的性能相对好些呢?
通过分析发现StringTokener.hasMoreElement和String.split(String.split是用正则表达式匹配,所以不使用KMP字符串匹配算法)用的都是按顺序遍历的算法,时间复杂度O(m*n),较高。
不过StringTokener是一边按顺序遍历,一边返回每个分组;而Spring.split是全部分组完成,再返回字符串数组。这个区别不大,但是如果我们不需要全部都分组,只需要某个分组的字符串,那么StringTokener性能会好点。
apacheJakatar的StringUtils一样用了KMP算法(按序查找字符串,时间是O(m+n)),按理说效率应该最高,但是为啥性能会比较差呢,需要进一步研究。不过有一个优点是如果使用一些转义字符
如“.”、“|”等不需要加"\",如果使用jdk的split必须加转义。
附源码:
String ip ="192.168.20.121";
long st1 = System.nanoTime();
String[] ips =ip.split("\\.");
System.out.println("使用jdk的split切分字符串");
for (int i = 0; i < ips.length; i++) {
System.out.print(ips[i]+" ");
}
System.out.println("花费时间"+(System.nanoTime()-st1));
long st2 = System.nanoTime();
ips= StringUtils.split(ip,"\\.");
System.out.println("使用common的split切分字符串");
for (int i = 0; i < ips.length; i++) {
System.out.print(ips[i]+" ");
}
System.out.println("花费时间"+(System.nanoTime()-st2));
long st3 = System.nanoTime();
System.out.println("使用StringTokenizer的切分字符串");
StringTokenizer token=new StringTokenizer(ip,".");
while(token.hasMoreElements()){
System.out.print(token.nextToken()+" ");
}
System.out.println("花费时间"+(System.nanoTime()-st3));
long st4 = System.nanoTime();
Pattern pattern = Pattern.compile("\\.");
ips =pattern.split(ip);
System.out.println("使用jdk的pattern切分字符串");
for (int i = 0; i < ips.length; i++) {
System.out.print(ips[i]+" ");
}
System.out.println("花费时间"+(System.nanoTime()-st4));
long st5 = System.nanoTime();
System.out.println("使用jdk的indexOf切分字符串");
int k=0,count=0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ip.length(); i++) {
if(ip.substring(i, i+1).equals(".")){
if(count==0){
System.out.print(ip.substring(0, i)+" ");
}else if(count==1){
System.out.print(ip.substring(k+1, i)+" ");
}else{
System.out.print(ip.substring(k+1, i)+" ");
System.out.print(ip.substring(i+1, ip.length())+" ");
}
k=i;count++;
}
}
System.out.println("花费时间"+(System.nanoTime()-st5));