http://blog.sina.com.cn/jingleq[订阅][手机订阅]
字体大小: 正文
java正则表达式效率(2007-06-04 12:41:38)
  对于正则表达式的使用效率问题,我在网上看到的有两种截然不同的结果,到底它的效率如何,今天我用java来做了个则试。
  解决的问题很简单,从一个字符串中把用正则表达式如href="[^\"]*"的字符串保存到一个list中去。先构造一个长字符串,再进行匹配操作。
测试代码如下:

import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Reg {

 public String content = "";

 public List userRegList = new LinkedList();
 public List userCommonList = new LinkedList();
 public List userOneToOneList = new LinkedList();

 //传入的参数为构造的字符串长度

 public void initContent(int count) {

  //选用StringBuffer,可以选用String一试,体现双方拼接字符串的效率差异
  StringBuffer sb = new StringBuffer();
  for (int i = 0; i < count / 20; i++) {

   //为了简化,统一用一小段来循环
   sb.append("abc href=\"abcd\"abce");
  }
  this.content = sb.toString();
 }

 //使用正则表达式方式

 public void useRegCode() {
  Pattern p = Pattern.compile("href=\"[^\"]*\"", Pattern.CANON_EQ);
  Matcher match = p.matcher(this.content);
  while (match.find()) {
   userRegList.add(match.group(0));
  }
 }

 // 主要使用字符串中提供的find函数来实现
 public void useCommonCode() {
  int i = 0;
  int index = 0;
  while ((index = content.indexOf("href=\"", i)) != -1) {
   int endIndex = content.indexOf("\"", index + 6);
   i = endIndex + 1;
   userCommonList.add(content.substring(index, endIndex + 1));
  }
 }

 // 一个一个字符地去遍历判断

 public void useOneToOneCode() {
  int length = content.length();
  for (int i = 0; i < length; i++) {

  //这里的实现有点依赖了目标的头字符了,为了简单忽略
   if (content.charAt(i) == 'h' && i + 5 < length
     && content.substring(i, i + 5).equals("href=")) {
    int j = i + 6;
    boolean match = false;
    for (; j < length; j++) {
     if (content.charAt(j) == '\"') {
      match = true;
      break;
     }
    }
    j++;
    if (match) {
     userOneToOneList.add(content.substring(i, j));
    }
    i = j;
   }
  }
 }

 

 //消耗时间记录,为了避免前后程序的干扰,在具体测试中,一个一个来测试记录时间

 public static void main(String[] args) {

  Reg r = new Reg();
  r.initContent(8000000);

  // 使用OneToOne
  long t5 = System.currentTimeMillis();
  r.useOneToOneCode();
  long t6 = System.currentTimeMillis();
  System.out.println("你的程序运行了:" + (int) ((t6 - t5) / 1000) + "秒"
    + ((t6 - t5) % 1000) + "毫秒");
  
  // 使用正则表达式
  long t3 = System.currentTimeMillis();
  r.useRegCode();
  long t4 = System.currentTimeMillis();
  System.out.println("你的程序运行了:" + (int) ((t4 - t3) / 1000) + "秒"
    + ((t4 - t3) % 1000) + "毫秒");
  
  // 使用find
  long t1 = System.currentTimeMillis();
  r.useCommonCode();
  long t2 = System.currentTimeMillis();
  System.out.println("你的程序运行了:" + (int) ((t2 - t1) / 1000) + "秒"
    + ((t2 - t1) % 1000) + "毫秒");
 }

}

  测试过程中,每种方式单独运行,数据量为8000000字符,数据如下,纵坐标单位为毫秒,横坐标单位为次,如图1.1

图1.1

  当数据量小的时候如800字符到8个字符,使用正则表达式大约需25毫秒(猜想,所用时间消耗在正则式的解释中),而其它两种方式不足1毫秒,若数据量为80000字符,使用正则表达式大约需45毫秒,而其它两种方式大约为14毫秒。

  通过这次测试,正则表达式在开发coding中,阅读和防止出bug上有很大好处,但是其性能依然值得注意。

 

加载中,请稍候...
  • 评论加载中,请稍候...

验证码:请点击后输入验证码  收听验证码

发评论

以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

相关博文
读取中...
推荐博文
读取中...