论坛首页 入门技术论坛

验证是否为数字(小数)的性能测试

浏览 2072 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-03-26   最后修改:2010-03-26

最近看了几本关于JAVA编程效率优化的数,感触颇多。刚好做到一个地方需要验证是否为数字(小数),Google了几个方法进行了比较和改进:

测试代码:

  public static boolean isNumeric1(String str) {
    for (int i = str.length(); --i >= 0;) {
      if (!Character.isDigit(str.charAt(i))) {
        return false;
      }
    }
    return true;
  }

  public static boolean isNumeric2(String str) {
    Pattern pattern = Pattern.compile("[0-9]*");
    return pattern.matcher(str).matches();
  }

  public static boolean isNumeric3(String str) {
    if (str.matches("\\d*")) {
      return true;
    } else {
      return false;
    }
  }

  public static boolean isNumeric4(String str) {
    for (int i = str.length(); --i >= 0;) {
      int chr = str.charAt(i);
      if (chr < 48 || chr > 57)
        return false;
    }
    return true;
  }

  /**
   * @param args
   */
  public static void main(String[] args) {
    long s1 = System.currentTimeMillis();
    for (int i = 0; i < 1000000; i++) {
      test.isNumeric1("1111111111111111111111111111111111111111111111d");
    }
    long s2 = System.currentTimeMillis();
    System.out.println("isNumeric1:" + (s2 - s1));
    for (int i = 0; i < 1000000; i++) {
      test.isNumeric2("1111111111111111111111111111111111111111111111d");
    }
    long s3 = System.currentTimeMillis();
    System.out.println("isNumeric2:" + (s3 - s2));
    for (int i = 0; i < 1000000; i++) {
      test.isNumeric3("1111111111111111111111111111111111111111111111d");
    }
     long s4 = System.currentTimeMillis();
     System.out.println("isNumeric3:" + (s4 - s3));
     for (int i = 0; i < 1000000; i++) {
     test.isNumeric4("1111111111111111111111111111111111111111111111d");
     }
     long s5 = System.currentTimeMillis();
     System.out.println("isNumeric4:" + (s5 - s4));
     for (int i = 0; i < 1000000; i++) {
     org.apache.commons.lang.StringUtils.isNumeric("1111111111111111111111111111111111111111111111d");
     }
     long s6 = System.currentTimeMillis();
     System.out.println("isNumeric5:" + (s6 - s5));
  }

 测试结果:

isNumeric1:42
isNumeric2:1614
isNumeric3:1355
isNumeric4:27
isNumeric5:195

 看起来isNumeric4胜出较多,但是先别下结论,将测试数据改为d111111111111111111111111111111111111111111111结果如下:

isNumeric1:65
isNumeric2:1305
isNumeric3:1087
isNumeric4:42
isNumeric5:104

 虽然优势不那么明显但还是isNumeric4胜出

 

改进:isNumeric4虽然快,但也只能分析正整数,因此调整其为:

  public static boolean isNumeric4(String str) {
    boolean flag = true;
    int length = str.length();
    for (int i = length; --i >= 0;) {
      int chr = str.charAt(i);
      if (chr < 48 || chr > 57) {
        if (i == 0 && (chr == 45 || chr == 43)) {
          continue;
        } else if (i != length -1 && i != 0 && (flag && chr == 46)) {
          flag = false;
          continue;
        } else {
          return false;
        }
      }
    }
    return true;
  }

 这样就可以基本识别小数并且最前面可以带“+”、“-”,再进行两次测试:

字符串为:1111111111111111111111111111111111111111111111d

isNumeric1:44
isNumeric2:1586
isNumeric3:1763
isNumeric4:38
isNumeric5:178
 

字符串为:d1111111111111111111111111111111111111111111111

isNumeric1:146
isNumeric2:1034
isNumeric3:672
isNumeric4:212
isNumeric5:98

 可见使用第二种字符串测试其性能低于了isNumeric1,但在功能上这点牺牲还是可以接受的。

 

虽然使用了超多次循环来测试,但每次的测试数据还是不能统一,可能和java虚拟机不同时候的性能有关系,所以这里只对同次测试的数据进行比较。

结论:考虑到各种情况,最优效率是将验证整数和整数(小数)分开,在能够判确认的情况下尽量使用整数验证。

 

 

 

论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics