Google Guava Splitter 对比 Apache StringUtils

Guava Splitter vs StringUtils

最近写了关于apache commons的StringUtils提供的常用功能介绍,见链接(http://vipcowrie.iteye.com/blog/1513017),但是我们知道google的guava也提供了一些字符串处理的常见功能,所以,我在本文将对两者的字符串分割函数做一次比较详细的对比(结果比较surprise)。

区别
首先看基本的使用方法:

Java代码 复制代码  收藏代码
  1. // Apache StringUtils...   
  2. String[] tokens1= StringUtils.split("one,two,three",',');   
  3.     
  4. // Google Guava splitter...   
  5. Iteratable<String> tokens2 = Splitter.on(','),split("one,two,three");  
// Apache StringUtils...
String[] tokens1= StringUtils.split("one,two,three",',');
 
// Google Guava splitter...
Iteratable<String> tokens2 = Splitter.on(','),split("one,two,three");



很明显,google提供的方法更加的面向对象一点,因为它要先创建一个Splitter对象,然后使用它来分割字符串,而apache的方法则有点函数式编程的味道,它的方法都是静态的。

这里我更加倾向于采用google的splitter,因为这个对象是可以重用的,且可以在其上附加更多的功能,比如trim,去掉空的元素等,一切都很简单。

Java代码 复制代码  收藏代码
  1. Splitter niceCommaSplitter = Splitter.on(',') .omitEmptyString().trimResults();   
  2. niceCommaSplitter.split("one,, two,  three"); //"one","two","three"   
  3. niceCommaSplitter.split("  four  ,  five  "); //"four","five"  
Splitter niceCommaSplitter = Splitter.on(',') .omitEmptyString().trimResults();
niceCommaSplitter.split("one,, two,  three"); //"one","two","three"
niceCommaSplitter.split("  four  ,  five  "); //"four","five"




看起来有点用,还有其他区别么?
另外一个需要注意的地方就是Splitter返回的是Iteratable<String>,而StringUtils.split返回的是一个String数组。

大部分使用分隔符的情况是我们需要对字符串按照分隔符进行遍历处理,仅此而已。
下面就是常用的代码性能对比的例子:

Java代码 复制代码  收藏代码
  1. final String numberList = "One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten";   
  2.   
  3. long start = System.currentTimeMillis();     
  4. for(int i=0; i<1000000; i++) {   
  5.     StringUtils.split(numberList , ',');      
  6. }   
  7. System.out.println(System.currentTimeMillis() - start);   
  8.      
  9. start = System.currentTimeMillis();   
  10. for(int i=0; i<1000000; i++) {   
  11.     Splitter.on(',').split(numberList );   
  12. }   
  13. System.out.println(System.currentTimeMillis() - start);  
final String numberList = "One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten";

long start = System.currentTimeMillis();  
for(int i=0; i<1000000; i++) {
    StringUtils.split(numberList , ',');   
}
System.out.println(System.currentTimeMillis() - start);
  
start = System.currentTimeMillis();
for(int i=0; i<1000000; i++) {
    Splitter.on(',').split(numberList );
}
System.out.println(System.currentTimeMillis() - start);

代码很简单,就是都对同一个字符串进行100万次的分隔操作,看看时间上的区别,结果如下:

Java代码 复制代码  收藏代码
  1. 983  
  2. 165  
983
165

很明显,guava的速度快很多,这个程序如果运行在每天处理大量字符串的服务中,那么性能差异更加明显。我想其中的原因是Splitter返回的是Iterable<String>,而StringUtils.split返回的是一个String[],需要创建新的String对象,导致耗时增加。

如果我们对Splitter对象缓存,那么速度提高更多:

Java代码 复制代码  收藏代码
  1. start = System.currentTimeMillis();   
  2.     Splitter s = Splitter.on(',');   
  3.     for (int i = 0; i < 1000000; i++) {   
  4.       s.split(numberList);   
  5.     }   
  6.     System.out.println(System.currentTimeMillis() - start);  
start = System.currentTimeMillis();
    Splitter s = Splitter.on(',');
    for (int i = 0; i < 1000000; i++) {
      s.split(numberList);
    }
    System.out.println(System.currentTimeMillis() - start);

结果为12,神奇吧,呵呵

别急,结果还没有出来,目前我们还没有对结果进行处理。我们试试对上面的结果进行处理:

Java代码 复制代码  收藏代码
  1. final String numberList = "One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten";   
  2.     long start = System.currentTimeMillis();   
  3.     for (int i = 0; i < 1000000; i++) {   
  4.       final String[] numbers = StringUtils.split(numberList, ',');   
  5.       for (String number : numbers) {   
  6.         number.length();   
  7.       }   
  8.     }   
  9.     System.out.println(System.currentTimeMillis() - start);   
  10.     start = System.currentTimeMillis();   
  11.     for (int i = 0; i < 1000000; i++) {   
  12.       Iterable<String> is = Splitter.on(',').split(numberList);   
  13.       for(String s:is) {   
  14.         s.length();   
  15.       }   
  16.     }   
  17.     System.out.println(System.currentTimeMillis() - start);   
  18.     start = System.currentTimeMillis();   
  19.     Splitter sp = Splitter.on(',');   
  20.     for (int i = 0; i < 1000000; i++) {   
  21.       Iterable<String> is =  sp.split(numberList);   
  22.       for(String s:is) {   
  23.         s.length();   
  24.       }   
  25.     }   
  26.     System.out.println(System.currentTimeMillis() - start);  
final String numberList = "One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten";
    long start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
      final String[] numbers = StringUtils.split(numberList, ',');
      for (String number : numbers) {
        number.length();
      }
    }
    System.out.println(System.currentTimeMillis() - start);
    start = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
      Iterable<String> is = Splitter.on(',').split(numberList);
      for(String s:is) {
        s.length();
      }
    }
    System.out.println(System.currentTimeMillis() - start);
    start = System.currentTimeMillis();
    Splitter sp = Splitter.on(',');
    for (int i = 0; i < 1000000; i++) {
      Iterable<String> is =  sp.split(numberList);
      for(String s:is) {
        s.length();
      }
    }
    System.out.println(System.currentTimeMillis() - start);



结果再次令人惊奇:

Java代码 复制代码  收藏代码
  1. 851  
  2. 2967  
  3. 2514  
851
2967
2514



guava比apache 的StringUtils慢3倍。

结论:
很明显,guava把处理时间较长的操作延迟到后面了,前期处理比较快。无论如何,我还是比较倾向于采用guava处理常见的字符串分隔任务,如果你要处理大量分隔后的字符串,且对性能比较关注,那可以使用StringUtils.split。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值