上一个帖子已经介绍了基本类型和引用类型的性能差异(主要是由于内存分配方式不同导致)。为了给列位看官加深印象,今天拿一个具体的例子来实地操作一把,看看优化的效果如何。
★关于需求
首先描述一下需求,具体如下:给定一个String对象,过滤掉除数字(字符'0'- '9')以外的其它字符。要求时间开销尽可能小。过滤函数的原型如下:String filter(String str);
针对上述需求,我写了5个不同的过滤函数。为了叙述方便,分别称为filter1到filter5。 其中filter1性能最差、filter5性能最好。在你接着看后续的内容之前,你先暗自思考一下,如果由你 来实现该函数,大概会写成什么样?最好把你想好的函数写下来,便于后面的对比。
★代码实现
◇测试代码
为了方便测试性能,先准备好一个测试代码,具体如下:
class Test
{
public static void main(String[] args)
{
if(args.length != 1)
{
return;
}
String str = "";
long nBegin = System.currentTimeMillis();
for(int i=0; i<1024*1024; i++)
{
str = filterN(args[0]); //此处调用某个具体的过滤函数
}
long nEnd = System.currentTimeMillis();
System.out.println(nEnd- nBegin);
System.out.println(str);
}
};
在没有想好你的实现方式之 前,先别偷看后续内容哦!另外,先注明下,我使用的Java环境是JDK 1.5.0-09,使用的测试字符串为 “D186783E36B721651E8AF96AB1C4000B”。由于机器性能不尽相同,你在自己机器上测试的 结果可能和我下面给出的数值不太一样,但趋势应该是差不多的。
◇版本1
先来揭晓性能 最差的filter1,代码如下:
private static String filter1(String strOld)
{
String strNew = new String();
for(int i=0; i<strOld.length(); i++)
{
if('0'<=strOld.charAt(i) && strOld.charAt(i) <='9')
{
strNew += strOld.charAt(i);
}
}
return strNew;
}
如果你的代码不幸和filter1雷同,那你的Java功底可就是相当糟糕了, 连字符串拼接需要用StringBuffer来优化都没搞明白。
为了和后续对比,先记下filter1的处理 时间,大约在8.81-8.90秒之间。
◇版本2
再来看看filter2,代码如下:
private static String filter2(String strOld)
{
StringBuffer strNew = new StringBuffer();
for(int i=0; i<strOld.length(); i++)
{
if('0'<=strOld.charAt(i) && strOld.charAt(i)<='9')
{
strNew.append(strOld.charAt(i));
}
}
return strNew.toString();
}
其实刚才在评价filter1的时候,已经泄露了filter2的天机。filter2通过使用 StringBuffer来优化连接字符串的性能。为什么StringBuffer连接字符串的性能比String好,这个已经 是老生常谈,我就不细说了。尚不清楚的同学自己上Google一查便知。我估计应该有挺多同学会写出类 似filter2的代码。
filter2的处理时间大约为2.14-2.18秒,提升了大约4倍。