1. 程式人生 > >java java中subString、split、stringTokenizer三種擷取字串方法的效能比較

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

copyprint?

  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 plaincopyprint?

  1. public String[] split(String regex, int limit) {  
  2.     return Pattern.compile(regex).split(this, limit)

本文來自 HH-i 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/u013938165/article/details/23173309?utm_source=copy