java java中subString、split、stringTokenizer三种截取字符串方法的性能比较

面试的时候,string  基本上是必须问的知识

突然想起面试的时候曾经被人问过:都知道在大数据量情况下,使用String的split截取字符串效率很低,有想过用其他的方法替代吗?用什么替代?我当时的回答很斩钉截铁:没有。

google了一下,发现有2中替代方法,于是在这里我将对这三种方式进行测试。

测试的软件环境为:Windows XP、eclipse、JDK1.6。

测试用例使用类ip形式的字符串,即3位一组,使用”.”间隔。数据分别使用:5组、10组、100组、1000组、10000组、100000组。

实现

闲话不说,先上代码:

[java]  view plain copy print ?
  1. package test.java.lang.ref;  
  2.   
  3. import java.util.Random;  
  4. import java.util.StringTokenizer;  
  5.   
  6. /** 
  7.  * String测试类 
  8.  * @author xiaori.Liu 
  9.  * 
  10.  */  
  11. public class StringTest {  
  12.       
  13.     public static void main(String args[]){  
  14.         String orginStr = getOriginStr(10);  
  15.           
  16.         //String.splic()表现//  
  17.         System.out.println("使用String.splic()的切分字符串");   
  18.         long st1 = System.nanoTime();   
  19.         String [] result = orginStr.split("\\.");  
  20.         System.out.println("String.splic()截取字符串用时:" + (System.nanoTime()-st1));  
  21.         System.out.println("String.splic()截取字符串结果个数:" + result.length);  
  22.         System.out.println();  
  23.           
  24.         //StringTokenizer表现//  
  25.         System.out.println("使用StringTokenizer的切分字符串");   
  26.         long st3 = System.nanoTime();    
  27.         StringTokenizer token=new StringTokenizer(orginStr,".");    
  28.         System.out.println("StringTokenizer截取字符串用时:"+(System.nanoTime()-st3));   
  29.         System.out.println("StringTokenizer截取字符串结果个数:" + token.countTokens());  
  30.         System.out.println();  
  31.           
  32.         String.substring()表现//  
  33.           
  34.           
  35.         long st5 = System.nanoTime();    
  36.         int len = orginStr.lastIndexOf(".");  
  37.         System.out.println("使用String.substring()切分字符串");    
  38.         int k=0,count=0;    
  39.           
  40.         for (int i = 0; i <= len; i++) {    
  41.          if(orginStr.substring(i, i+1).equals(".")){    
  42.           if(count==0){    
  43.            orginStr.substring(0, i);    
  44.           }else{    
  45.              orginStr.substring(k+1, i);   
  46.              if(i == len){  
  47.                orginStr.substring(len+1, orginStr.length());   
  48.            }  
  49.           }  
  50.           k=i;count++;    
  51.          }    
  52.         }  
  53.         System.out.println("String.substring()截取字符串用时"+(System.nanoTime()-st5));    
  54.         System.out.println("String.substring()截取字符串结果个数:" + (count + 1));  
  55.     }  
  56.       
  57.     /** 
  58.      * 构造目标字符串 
  59.      * eg:10.123.12.154.154 
  60.      * @param len 目标字符串组数(每组由3个随机数组成) 
  61.      * @return 
  62.      */  
  63.     private static String getOriginStr(int len){  
  64.           
  65.         StringBuffer sb = new StringBuffer();  
  66.         StringBuffer result = new StringBuffer();  
  67.         Random random = new Random();  
  68.         for(int i = 0; i < len; i++){  
  69.             sb.append(random.nextInt(9)).append(random.nextInt(9)).append(random.nextInt(9));  
  70.             result.append(sb.toString());  
  71.             sb.delete(0, sb.length());  
  72.             if(i != len-1)  
  73.                 result.append(".");  
  74.         }  
  75.           
  76.         return result.toString();  
  77.     }  
  78. }  


改变目标数据长度修改getOriginStr的len参数即可。

5组测试数据结果如下图:


下面这张图对比了下,split耗时为substring和StringTokenizer耗时的倍数:

好吧,我又花了点儿时间,做了几张图表来分析这3中方式的性能。

首先来一张柱状图对比一下这5组数据截取所花费的时间:

从上图可以看出StringTokenizer的性能实在是太好了(对比另两种),几乎在图表中看不见它的身影。遥遥领先。substring花费的时间始终比split要少,但是耗时也在随着数据量的增加而增加。

下面3张折线图可以很明显看出split、substring、StringTokenizer3中实现随着数据量增加,耗时的趋势。

split是变化最大的,也就是数据量越大,截取所需要的时间增长越快。

substring则比split要平稳一点点,但是也在增长。

StringTokenizer则是表现最优秀的,基本上平稳,始终保持在5000ns一下。

结论

最终,StringTokenizer在截取字符串中效率最高,不论数据量大小,几乎持平。substring则要次之,数据量增加耗时也要随之增加。split则是表现最差劲的。

究其原因,split的实现方式是采用正则表达式实现,所以其性能会比较低。至于正则表达式为何低,还未去验证。split源码如下:

[java]  view plain copy print ?
  1. public String[] split(String regex, int limit) {  
  2.     return Pattern.compile(regex).split(this, limit)

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值