定时操作产生不可能的结果

时间:2012-05-16 14:15:48

标签: java performance unit-testing testing timer

我正在尝试将几种方法相互对比,并且出于某种原因我得到了不可能的结果。显然,有些操作比整个应用程序运行时间要长得多。我已经搜索了所有内容,由于某种原因,我无法确定我做错了什么,所以我很抱歉,但我发布了整个方法: - /

public static void parseNumber() throws Exception {
  long numberHelperTotal = 0;
  long numberUtilsTotal = 0;
  long regExTotal = 0;
  long bruteForceTotal = 0;
  long scannerTotal = 0;
  int iterations = 10;
  for (int i = 0; i < iterations; i++) {
    long numberHelper = 0;
    long numberUtils = 0;
    long regEx = 0;
    long bruteForce = 0;
    long scanner = 0;
    for (int j = 0; j < 999999; j++) { // I know 999999 is a bit overkill... I've tried it with smaller values and it still yields impossible results
      Date start; //I think it may have something to do with the way I'm doing start and end...
      Date end;
      Random rand = new Random();
      String string = ((rand.nextBoolean()) ? "" : "-") + String.valueOf(rand.nextDouble() * j);

      //NumberHelper
      start = new Date();
      NumberHelper.isValidNumber(double.class, string);
      end = new Date();
      numberHelper += end.getTime() - start.getTime();

      //NumberUtils
      start = new Date();
      NumberUtils.isNumber(string);
      end = new Date();
      numberUtils += end.getTime() - start.getTime();

      //RegEx
      start = new Date();
      Pattern p = Pattern.compile("^[-+]?[0-9]*\\.?[0-9]+$");
      Matcher m = p.matcher(string);
      if (m.matches()) {
        Double.parseDouble(string);
      }
      end = new Date();
      regEx += end.getTime() - start.getTime();

      //Brute Force (not international support) and messy support for E and negatives
      //This is not the way to do it...
      start = new Date();
      int decimalpoints = 0;
      for (char c : string.toCharArray()) {
        if (Character.isDigit(c)) {
          continue;
        }
        if (c != '.') {
          if (c == '-' || c == 'E') {
            decimalpoints--;
          } else {
            //return false
            //because it should never return false in this test, I will throw an exception here if it does.
            throw new Exception("Brute Force returned false! It doesn't work! The character is " + c + " Here's the number: " + string);
          }
        }
        if (decimalpoints > 0) {
          //return false
          //because it should never return false in this test, I will throw an exception here if it does.
          throw new Exception("Brute Force returned false! It doesn't work! The character is " + c + " Here's the number: " + string);
        }
        decimalpoints++;
      }
      end = new Date();
      bruteForce += end.getTime() - start.getTime();

      //Scanner
      start = new Date();
      Scanner scanNumber = new Scanner(string);
      if (scanNumber.hasNextDouble()) {//check if the next chars are integer
        //return true;
      } else {
        //return false;
        //because it should never return false in this test, I will throw an exception here if it does.
        throw new Exception("Scanner returned false! It doesn't work! Here's the number: " + string);
      }
      end = new Date();
      scanner += end.getTime() - start.getTime();

      //Increase averages
      numberHelperTotal += numberHelper;
      numberUtilsTotal += numberUtils;
      regExTotal += regEx;
      bruteForceTotal += bruteForce;
      scannerTotal += scanner;
      //For debug:
      //System.out.println("String: " + string);
      //System.out.println("NumberHelper: " + numberHelper);
      //System.out.println("NumberUtils: " + numberUtils);
      //System.out.println("RegEx: " + regEx);
      //System.out.println("Brute Force: " + bruteForce);
      //System.out.println("Scanner: " + scanner);
    }
  }

示例输出:

First: NumberUtils - 83748758 milliseconds
Second: Brute Force - 123797252 milliseconds
Third: NumberHelper - 667504094 milliseconds
Fourth: RegEx - 2540545193 milliseconds
Fifth: Scanner - 23447108911 milliseconds

2 个答案:

答案 0 :(得分:2)

使用System.nanoTime(),这实际上是用于&#34;在运行过程中两次之间取差异。&#34;

或者,很多更好的想法 - 使用预先构建的Java基准测试框架,该框架已经知道如何预热JIT以及为获得准确的基准测试结果而需要做的所有其他事情。 Caliper可能是最知名的。

答案 1 :(得分:0)

以下5行似乎位置不正确:

//Increase averages
numberHelperTotal += numberHelper;
numberUtilsTotal += numberUtils;
regExTotal += regEx;
bruteForceTotal += bruteForce;
scannerTotal += scanner;

尝试将它们放在for (int j ...循环之外。