Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4411600

Byte buffers significantly slower than arrays in C1

XMLWordPrintable

    • beta2
    • generic
    • generic

      The following program demonstrates that accessing elements of a byte buffer is
      significantly slower with C1 than accessing elements of an array:

          % /usr/local/java/jdk1.4/linux-i386/bin/java -client -showversion BBSpeed
          java version "1.4.0-beta"
          Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b50)
          Java HotSpot(TM) Client VM (build 1.4beta-B50, mixed mode)

          array 225
          array rev 286
          heap 1147
          heap rev 1148
          direct 3301
          direct rev 3304
          %

      I get similar numbers on Solaris (times are in ms).

      (The numbers for direct byte buffers are even worse than those for
       heap-allocated byte buffers due to the fact that C1 does not yet inline
       sun.misc.Unsafe operations (4411596).)

      Making both heap and direct buffers perform as well as arrays (or nearly so) is
      critical to the performance of the java.nio subsystem.

      -- mr@eng 2001/2/4


      ---- BBSpeed.java

      import java.nio.*;


      public class BBSpeed {

          static final int SIZE = 4096;
          static final int TRIALS = 4096;

          static int sum(ByteBuffer bb) {
      int n = bb.capacity();
      int a = 0;
      bb.rewind();
      for (int j = 0; j < n; j++)
      a += bb.get(j);
      return a;
          }

          static int sumReverse(ByteBuffer bb) {
      int n = bb.capacity();
      int a = 0;
      bb.rewind();
      for (int j = n - 1; j >= 0; j--)
      a += bb.get(j);
      return a;
          }

          static int time(String name, ByteBuffer bb) {
      int n = bb.capacity();
      bb.limit(bb.capacity());
      int a = 0;

      for (int i = 0; i < TRIALS; i++) sum(bb);
      long start = System.currentTimeMillis();
      for (int i = 0; i < TRIALS; i++) sum(bb);
      System.out.println(name + " " + (System.currentTimeMillis() - start));

      for (int i = 0; i < TRIALS; i++) sumReverse(bb);
      start = System.currentTimeMillis();
      for (int i = 0; i < TRIALS; i++) sumReverse(bb);
      System.out.println(name + " rev " + (System.currentTimeMillis() - start));

      return a;
          }

          static int sum(byte[] ba) {
      int n = ba.length;
      int a = 0;
      for (int j = 0; j < n; j++)
      a += ba[j];
      return a;
          }

          static int sumReverse(byte[] ba) {
      int n = ba.length;
      int a = 0;
      for (int j = n - 1; j >= 0; j--)
      a += ba[j];
      return a;
          }

          static int timeArray() {
      byte[] ba = new byte[SIZE];
      int a = 0;

      for (int i = 0; i < TRIALS; i++) a += sum(ba);
      long start = System.currentTimeMillis();
      for (int i = 0; i < TRIALS; i++) a += sum(ba);
      System.out.println("array " + (System.currentTimeMillis() - start));

      for (int i = 0; i < TRIALS; i++) a += sumReverse(ba);
      start = System.currentTimeMillis();
      for (int i = 0; i < TRIALS; i++) a += sumReverse(ba);
      System.out.println("array rev " + (System.currentTimeMillis() - start));

      return a;
          }

          public static void main(String[] args) {
      String key = "hda";
      if (args.length == 1)
      key = args[0];
      int a = 0;
      if (key.indexOf('a') >= 0)
      a += timeArray();
      if (key.indexOf('h') >= 0)
      a += time("heap", ByteBuffer.allocate(SIZE));
      if (key.indexOf('d') >= 0)
      a += time("direct", ByteBuffer.allocateDirect(SIZE));
      System.exit(a);
          }

      }

            never Tom Rodriguez
            mr Mark Reinhold
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: