java中subString、split、stringTokenizer三种截取字符串方法的性能比较(转)
最近在阅读java.lang下的源码,读到String时,突然想起面试的时候曾经被人问过:都知道在大数据量情况下,使用String的split截取字符串效率很低,有想过用其他的方法替代吗?用什么替代?我当时的回答很斩钉截铁:没有。
google了一下,发现有2中替代方法,于是在这里我将对这三种方式进行测试。
测试的软件环境为:Windows XP、eclipse、JDK1.6。
测试用例使用类ip形式的字符串,即3位一组,使用”.”间隔。数据分别使用:5组、10组、100组、1000组、10000组、100000组。
实现
闲话不说,先上代码:
package test.java.lang.ref; import java.util.Random;
import java.util.StringTokenizer; /**
* String测试类
* @author xiaori.Liu
*
*/
public class StringTest { public static void main(String args[]){
String orginStr = getOriginStr(10); //////////////String.splic()表现//////////////////////////////////////////////
System.out.println("使用String.splic()的切分字符串");
long st1 = System.nanoTime();
String [] result = orginStr.split("\\.");
System.out.println("String.splic()截取字符串用时:" + (System.nanoTime()-st1));
System.out.println("String.splic()截取字符串结果个数:" + result.length);
System.out.println(); //////////////StringTokenizer表现//////////////////////////////////////////////
System.out.println("使用StringTokenizer的切分字符串");
long st3 = System.nanoTime();
StringTokenizer token=new StringTokenizer(orginStr,".");
System.out.println("StringTokenizer截取字符串用时:"+(System.nanoTime()-st3));
System.out.println("StringTokenizer截取字符串结果个数:" + token.countTokens());
System.out.println(); ////////////////////String.substring()表现////////////////////////////////////////// long st5 = System.nanoTime();
int len = orginStr.lastIndexOf(".");
System.out.println("使用String.substring()切分字符串");
int k=0,count=0; for (int i = 0; i <= len; i++) {
if(orginStr.substring(i, i+1).equals(".")){
if(count==0){
orginStr.substring(0, i);
}else{
orginStr.substring(k+1, i);
if(i == len){
orginStr.substring(len+1, orginStr.length());
}
}
k=i;count++;
}
}
System.out.println("String.substring()截取字符串用时"+(System.nanoTime()-st5));
System.out.println("String.substring()截取字符串结果个数:" + (count + 1));
} /**
* 构造目标字符串
* eg:10.123.12.154.154
* @param len 目标字符串组数(每组由3个随机数组成)
* @return
*/
private static String getOriginStr(int len){ StringBuffer sb = new StringBuffer();
StringBuffer result = new StringBuffer();
Random random = new Random();
for(int i = 0; i < len; i++){
sb.append(random.nextInt(9)).append(random.nextInt(9)).append(random.nextInt(9));
result.append(sb.toString());
sb.delete(0, sb.length());
if(i != len-1)
result.append(".");
} return result.toString();
}
}
改变目标数据长度修改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源码如下:
public String[] split(String regex, int limit) {
return Pattern.compile(regex).split(this, limit);
}
http://blog.csdn.net/songylwq/article/details/9016609
java中subString、split、stringTokenizer三种截取字符串方法的性能比较(转)的更多相关文章
- Java中终止线程的三种方法
终止线程一般建议采用的方法是让线程自行结束,进入Dead(死亡)状态,就是执行完run()方法.即如果想要停止一个线程的执行,就要提供某种方式让线程能够自动结束run()方法的执行.比如设置一个标志来 ...
- Java中创建线程的三种方法以及区别
Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例.Java可以用三种方式来创建线程,如下所示: 1)继承Thread类创建线程 2)实现Runnable接口创建线 ...
- java中遍历集合的三种方式
第一种遍历集合的方式:将集合变为数组 package com.lw.List; import java.util.ArrayList; import java.util.List; import ja ...
- JAVA中创建线程的三种方法及比较
JAVA中创建线程的方式有三种,各有优缺点,具体如下: 一.继承Thread类来创建线程 1.创建一个任务类,继承Thread线程类,因为Thread类已经实现了Runnable接口,然后重写run( ...
- Java中List集合的三种遍历方式(全网最详)
List集合在Java日常开发中是必不可少的,只要懂得运用各种各样的方法就可以大大提高我们开发的效率,适当活用各种方法才会使我们开发事半功倍. 我总结了三种List集合的遍历方式,下面一一来介绍. 首 ...
- Java中创建线程的三种方式以及区别
在java中如果要创建线程的话,一般有3种方法: 继承Thread类: 实现Runnable接口: 使用Callable和Future创建线程. 1. 继承Thread类 继承Thread类的话,必须 ...
- java中 this 关键字的三种用法
Java中this的三种用法 调用属性 (1)this可以调用本类中的任何成员变量 调用方法(可省略) (2)this调用本类中的成员方法(在main方法里面没有办法通过this调用) 调用构造方法 ...
- java中终止线程的三种方式
在java中有三种方式可以终止线程.分别为: 1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止. 2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和sus ...
- js常用的4种截取字符串方法
平常经常把这几个api的参数记混了,于是打算记录下来,当不确定的时候在拿出来翻翻: 在做项目的时候,经常会需要截取字符串,所以常用的方法有slice().substr().substring().ma ...
随机推荐
- Lucene核心--构建Lucene搜索(下篇,理论篇)
2.1.6 截取索引(Indextruncate) 一些应用程序的所以文档的大小先前是不知道的.作为控制RAM和磁盘存储空间的使用数量的安全机制,你可能想要限制每个字段允许输入索引的输入数量.一个大的 ...
- fragment的切换
1.视图 1)主视图 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xml ...
- IOS中的数据存储 简单总结
1. NSKeyedArchiver(加密形式) 2. plist 3. NSUserDefaults 4. writeToFile 5. SQLite3 ==== N ...
- 07-UIKit(tableview的编辑模式、accessoryView)
目录: 一.tableview的编辑模式-增删改查 二.不使用继承创建tableview 三.accessoryView辅助视图 回到顶部 一.tableview的编辑模式-增删改查 [1-conta ...
- boost:regex分割字符串(带有'\'字符) - zzusimon的专栏 - 博客频道 - CSDN.NET
boost:regex分割字符串(带有'\'字符) - zzusimon的专栏 - 博客频道 - CSDN.NET boost:regex分割字符串(带有'\'字符) 分类: C++ 2011-08- ...
- Oculus Rift DK2 安装所需电脑配置
系统支持:眼下使用的SDK0.4支持windows7,windows8,windows8.1.Mac(10.8,10.9): 硬件配置:官方给的标准配置为2.0+GHz以上CPU.2GB内存.兼容Di ...
- Laravel创建Model
它已被用于CI框架.最近学习使用Laravel框架,要总结一些遇到的问题是一个创纪录,供以后调用.此外,我希望能够碰到同样的问题的朋友的帮助. 在Laravel数据库表是根据Laravel写好的程序去 ...
- Java8 Lamdba表达式 001
在一个已经存在的编程语言里非常少有对现有的生态系统起重大影响的新特性.Lambda表达式对于Java语言就是这样的意义的存在.简单来说,Lambda表达式提供了便利的方式去创建一个匿名的功能.提供了一 ...
- [Android] 更改关联的源码路径
右击选中工程 → Java Build Path → Libraries → Android 4.1.2 → 点开android.jar → 选中Source attachment → Edit,即可 ...
- HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011亚洲北京赛区网络赛)
HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011 亚洲北京赛区网络赛题目) Eliminate Witches! Time Limit: 2000/1000 ...