示例#1
0
  /**
   * This method is for comparing the speed of the ArrayCoreMap family and HashMap. It tests random
   * access speed for a fixed number of accesses, i, for both a CoreLabel (can be swapped out for an
   * ArrayCoreMap) and a HashMap. Switching the order of testing (CoreLabel first or second) shows
   * that there's a slight advantage to the second loop, especially noticeable for small i - this is
   * due to some background java funky-ness, so we now run 50% each way.
   */
  @SuppressWarnings({"StringEquality"})
  public static void main(String[] args) {
    @SuppressWarnings("unchecked")
    Class<CoreAnnotation<String>>[] allKeys =
        new Class[] {
          CoreAnnotations.TextAnnotation.class,
          CoreAnnotations.LemmaAnnotation.class,
          CoreAnnotations.PartOfSpeechAnnotation.class,
          CoreAnnotations.ShapeAnnotation.class,
          CoreAnnotations.NamedEntityTagAnnotation.class,
          CoreAnnotations.DocIDAnnotation.class,
          CoreAnnotations.ValueAnnotation.class,
          CoreAnnotations.CategoryAnnotation.class,
          CoreAnnotations.BeforeAnnotation.class,
          CoreAnnotations.AfterAnnotation.class,
          CoreAnnotations.OriginalTextAnnotation.class,
          CoreAnnotations.ArgumentAnnotation.class,
          CoreAnnotations.MarkingAnnotation.class
        };

    // how many iterations
    final int numBurnRounds = 10;
    final int numGoodRounds = 60;
    final int numIterations = 2000000;
    final int maxNumKeys = 12;
    double gains = 0.0;

    for (int numKeys = 1; numKeys <= maxNumKeys; numKeys++) {
      // the HashMap instance
      HashMap<String, String> hashmap = new HashMap<String, String>(numKeys);

      // the CoreMap instance
      CoreMap coremap = new ArrayCoreMap(numKeys);

      // the set of keys to use
      String[] hashKeys = new String[numKeys];
      @SuppressWarnings("unchecked")
      Class<CoreAnnotation<String>>[] coreKeys = new Class[numKeys];
      for (int key = 0; key < numKeys; key++) {
        hashKeys[key] = allKeys[key].getSimpleName();
        coreKeys[key] = allKeys[key];
      }

      // initialize with default values
      for (int i = 0; i < numKeys; i++) {
        coremap.set(coreKeys[i], String.valueOf(i));
        hashmap.put(hashKeys[i], String.valueOf(i));
      }

      assert coremap.size() == numKeys;
      assert hashmap.size() == numKeys;

      // for storing results
      double[] hashTimings = new double[numGoodRounds];
      double[] coreTimings = new double[numGoodRounds];

      final Random rand = new Random(0);
      boolean foundEqual = false;
      for (int round = 0; round < numBurnRounds + numGoodRounds; round++) {
        System.err.print(".");
        if (round % 2 == 0) {
          // test timings on hashmap first
          final long hashStart = System.nanoTime();
          final int length = hashKeys.length;
          String last = null;
          for (int i = 0; i < numIterations; i++) {
            int key = rand.nextInt(length);
            String val = hashmap.get(hashKeys[key]);
            if (val == last) {
              foundEqual = true;
            }
            last = val;
          }
          if (round >= numBurnRounds) {
            hashTimings[round - numBurnRounds] = (System.nanoTime() - hashStart) / 1000000000.0;
          }
        }
        { // test timings on coremap
          final long coreStart = System.nanoTime();
          final int length = coreKeys.length;
          String last = null;
          for (int i = 0; i < numIterations; i++) {
            int key = rand.nextInt(length);
            String val = coremap.get(coreKeys[key]);
            if (val == last) {
              foundEqual = true;
            }
            last = val;
          }
          if (round >= numBurnRounds) {
            coreTimings[round - numBurnRounds] = (System.nanoTime() - coreStart) / 1000000000.0;
          }
        }
        if (round % 2 == 1) {
          // test timings on hashmap second
          final long hashStart = System.nanoTime();
          final int length = hashKeys.length;
          String last = null;
          for (int i = 0; i < numIterations; i++) {
            int key = rand.nextInt(length);
            String val = hashmap.get(hashKeys[key]);
            if (val == last) {
              foundEqual = true;
            }
            last = val;
          }
          if (round >= numBurnRounds) {
            hashTimings[round - numBurnRounds] = (System.nanoTime() - hashStart) / 1000000000.0;
          }
        }
      }
      if (foundEqual) {
        System.err.print(" [found equal]");
      }
      System.err.println();

      double hashMean = ArrayMath.mean(hashTimings);
      double coreMean = ArrayMath.mean(coreTimings);
      double percentDiff = (hashMean - coreMean) / hashMean * 100.0;
      NumberFormat nf = new DecimalFormat("0.00");
      System.out.println("HashMap @ " + numKeys + " keys: " + hashMean + " secs/2million gets");
      System.out.println(
          "CoreMap @ "
              + numKeys
              + " keys: "
              + coreMean
              + " secs/2million gets ("
              + nf.format(Math.abs(percentDiff))
              + "% "
              + (percentDiff >= 0.0 ? "faster" : "slower")
              + ")");
      gains += percentDiff;
    }
    System.out.println();
    gains = gains / maxNumKeys;
    System.out.println(
        "Average: " + Math.abs(gains) + "% " + (gains >= 0.0 ? "faster" : "slower") + ".");
  }