`
cowboy_bebop
  • 浏览: 110371 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

一个Java字符串过滤函数的性能优化

    博客分类:
  • J2SE
阅读更多

一、需求

  给定一个String对象,过滤掉除数字(字符'0'-'9')以外的其它字符。要求时间开销尽可能小。过滤函数的原型如下: String filter(String str);

 

二、代码测试

 

public static void main(String[] args) {
	String str = "";
	long begin = System.currentTimeMillis();
	for(int i=0;i<1024*1024;i++) {
		str = filter7("D186783E36B721651E8AF96AB1C4000B");
	}
	long end = System.currentTimeMillis();
	System.out.println("测试用时:"+(end-begin));
	System.out.println(str);
}
 

 

三、不同版本

      

        /**
	 * 过滤方法-1-
	 * 测试用时:4328
	 * 运行结果:1867833672165189614000
	 * 注:这种方法效果是最差的,拼接字符串时 起码也要想到StringBuffer或StringBuilder
	 */
	public static String filter1(String str) {
		String newStr = new String();
		for(int i=0;i<str.length();i++) {
			if(str.charAt(i) >= '0' && str.charAt(i) <= '9') {
				newStr +=  str.charAt(i);
			}
		}
		return newStr;
	}
	
	/**
	 * 过滤方法-2-
	 * 测试用时:1656
	 * 运行结果:1867833672165189614000
	 * 注:使用StringBuffer后效率明显提高了
	 */
	public static String filter2(String str) {
		StringBuffer sb = new StringBuffer();
		for(int i=0;i<str.length();i++) {
			if(str.charAt(i) >= '0' && str.charAt(i) <= '9') {
				sb.append(str.charAt(i));
			}
		}
		return sb.toString();
	}
	
	/**
	 * 过滤方法-3-
	 * 测试用时:625
	 * 运行结果:1867833672165189614000
	 * 注:使用StringBuilder后效率也有不错的提升,因为StringBuffer是线程安全的它的方法都是同步的,
	 * 因此调用他的方法有一定的同步开销
	 */
	public static String filter3(String str) {
		StringBuilder sb = new StringBuilder();
		for(int i=0;i<str.length();i++) {
			if(str.charAt(i) >= '0' && str.charAt(i) <= '9') {
				sb.append(str.charAt(i));
			}
		}
		return sb.toString();
	}
	
	/**
	 * 过滤方法-4-
	 * 测试用时:625
	 * 运行结果:1867833672165189614000
	 * 注:循环时就不必每次都计算一下传入的字符串的长度了,但是发现效率没有提升,可能是jdk自己做了优化
	 */
	public static String filter4(String str) {
		StringBuilder sb = new StringBuilder();
		int length = str.length();
		for(int i=0;i<length;i++) {
			if(str.charAt(i) >= '0' && str.charAt(i) <= '9') {
				sb.append(str.charAt(i));
			}
		}
		return sb.toString();
	}
	
	/**
	 * 过滤方法-5-
	 * 测试用时:594
	 * 运行结果:1867833672165189614000
	 * 注:通过StringBuilder的构造函数设置初始的容量大小,可以有效避免append()追加字符时重新分配内存,从而提高性能.
	 */
	public static String filter5(String str) {
		int length = str.length();
		StringBuilder sb = new StringBuilder(length);
		for(int i=0;i<length;i++) {
			if(str.charAt(i) >= '0' && str.charAt(i) <= '9') {
				sb.append(str.charAt(i));
			}
		}
		return sb.toString();
	}
	
	/**
	 * 过滤方法-6-
	 * 测试用时:562
	 * 运行结果:1867833672165189614000
	 * 注:少了个str.charAt(i)提升效果不明显
	 */
	public static String filter6(String str) {
		int length = str.length();
		StringBuilder sb = new StringBuilder(length);
		for(int i=0;i<length;i++) {
			char ch = str.charAt(i);
			if(ch >= '0' && ch <= '9') {
				sb.append(ch);
			}
		}
		return sb.toString();
	}
	
	/**
	 * 过滤方法-7-
	 * 测试用时:406
	 * 运行结果:1867833672165189614000
	 * 注:相比filter6 7里面有字符数组创建的开销, 而StringBuilder也有字符数组创建的开销.
	 *     二者差别就在于7少了StringBuilder对象创建的开销
	 */
	public static String filter7(String str) {
		int length = str.length();
		char[] chArray = new char[length];
		int index = 0;
		for(int i=0;i<length;i++) {
			char ch = str.charAt(i);
			if(ch >= '0' && ch <= '9') {
				chArray[index] = ch;
				index++;
			}
		}
		return new String(chArray,0,index);
	}
 

四、补充

      版本6和版本7使用了空间换时间的手法来提升性能。假如被过滤的字符串很大,并且数字字符的比例很低,这种方式就不太合算了。

   举个例子:被处理的字符串中,绝大部分都只含有不到10%的数字字符,只有少数字符串包含较多的数字字符。这时候该怎么办捏?对于filter6来说,可以把new StringBuffer(nLen);修改为new StringBuffer(nLen/10);来节约空间开销。但是filter7就没法这么玩了。
   所以,具体该用版本6还是版本7,要看具体情况了。只有在你非常看重时间开销,且数字字符比例很高(至少大于50%)的情况下,用filter7才合算。否则的话,建议用filter6。

 

 

 

分享到:
评论

相关推荐

    Java开发技术大全(500个源代码).

    HelloWorldApp.java 第一个用Java开发的应用程序。 firstApplet.java 第一个用Java开发的Applet小程序。 firstApplet.htm 用来装载Applet的网页文件 第2章 示例描述:本章介绍开发Java的基础语法知识。 ...

    JAVA上百实例源码以及开源项目

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    Java基础知识点总结.docx

    无论是工作学习,不断的总结是必不可少的。只有不断的总结,发现问题,弥补不足,才能长久的进步!!Java学习更是如此,知识点总结目录如下: 目录 一、 Java概述 3 二、 Java语法基础 5 ...Java 性能优化 362

    JAVA上百实例源码以及开源项目源代码

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    使用Java的日期和时间处理实现一个简单的日程安排管理系统.txt

    addAppointment()方法用于添加新的预约信息,它接收一个描述和一个Date对象作为参数,并将它们拼接成一个字符串后添加到appointments列表中。然后调用saveAppointments()方法将更新后的预约信息保存到文件中。...

    SQLServer2008查询性能优化 2/2

    9.8.4 实现准备/执行模式以避免重传查询字符串 253 9.8.5 避免即席查询 253 9.8.6 对于动态查询sp_executesql优于EXECUTE 253 9.8.7 小心地参数化查询的可变部分 254 9.8.8 不要允许查询中对象的隐含解析 254 ...

    java 正则表达式

    应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)String.prototype.len=function(){return this.replace(/[^\x00-\xff]/g,"aa").length;} 匹配空行的正则表达式:\n[\s| ]*\r 匹配html标签的正则...

    java 算法

    简介:这份资源是我以前偶然...递归,拷贝一个目录或者文件到指定路径下,简单的txt转换xml,字母排序(A-Z)(先大写,后小写),列出某文件夹及其子文件夹下面的文件,并可根据扩展名过滤,字符串匹配的算法,写入日志。

    Visual C++ 2005入门经典--源代码及课后练习答案

    4.1.4 字符数组和字符串处理 147 4.1.5 多维数组 150 4.2 间接数据存取 153 4.2.1 指针的概念 153 4.2.2 声明指针 154 4.2.3 使用指针 155 4.2.4 初始化指针 157 4.2.5 sizeof运算符 162 4.2.6 ...

    java开源包4

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

    java开源包11

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

    java开源包6

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

    java开源包101

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

    java开源包9

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

    SQLServer2008查询性能优化 1/2

    9.8.4 实现准备/执行模式以避免重传查询字符串 253 9.8.5 避免即席查询 253 9.8.6 对于动态查询sp_executesql优于EXECUTE 253 9.8.7 小心地参数化查询的可变部分 254 9.8.8 不要允许查询中对象的隐含解析 254 ...

    java开源包5

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

    java开源包8

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

    java开源包10

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

    java开源包1

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

Global site tag (gtag.js) - Google Analytics