hotspot-dev Digest, Vol 84, Issue 18

Cleber Muramoto cleber at nightcoders.com.br
Tue Apr 8 19:57:18 UTC 2014


Hi Aleksey, the code essentially uses specialized classes to avoid
reflection during serialization. I will try to "proxy" the test bellow, if
you need more details please let me know.

Given

public class A{

   int i;
   long j;
   //can have references as well
}

There will be an associated serializer to read/write A instances:

public class A$Ser implements Serializer {

   @Override
   public void write(Object o, ByteBuffer dst){
     //writes class metadata
     doWrite(o,dst);
   }

   //writes object's payload
   @Override
   public void doWrite(Object o, ByteBuffer dst){
      A a = (A)o;
      dst.putInt(a.i);
      dst.putLong(a.j);
   }

   //reads object's payload
   @Override
   public void doRead(Object o, ByteBuffer src){
       A a = (A)o;
       a.i=dst.getInt();
       b.j=dst.getLong();
   }

   @Override
   public A read(ByteBuffer src){
       //reads metadata and instantiate
       A a =new A();
       doRead(a,src);
       return a;
   }
}

The benchmark code essentially does:

ForkJoinPool fjp = ...(created using Available Processors = 48)
final ByteBuffer bb=ByteBuffer.allocateDirect(HUGE_BLOCK);
int[] index=new int[max];

//writes are always serial on the test

for(int i=0;i<max;i++){
   A a = createRandomA();
   index[i] = bb.position();
   serializer.write(bb,a);
}

bb.flip();


//Serial reads
long start = System.currentTimeMillis();

for(int i=0;i<max;i++){
  A a = serializer.read(buff);
  Assert.assertNotNull(a);
  //other consitency checks (these don't have much impact on performance)
}

long elapsed = System.currentTimeMillis() -start;

For the parallel code, I'm using an old (but still excellent!!!) version of
Doug Lea's concurrency utilities, one that had the ParallelArray class. I
repackaged it so that it uses the ForkJoinPool and other concurrency
classes provided by the JDK.

//Callback Interface to operate on every element of an array
IntProcedure ip = new IntProcedure(){

    @Override
    public void op(int key) {
       ByteBuffer buff = bb.duplicate().position(key);
       A a = serializer.read(buff);
       Assert.assertNotNull(a);
    }
};

long start = System.currentTimeMillis();

ParrallelIntArray.createUsingHandoff(index,pool).apply(ip);

long elapsed = System.currentTimeMillis() - start;

The actual class used in the test is a complex object graph, but the idea
is pretty much the same.

-Cleber

On Tue, Apr 8, 2014 at 10:22 AM, <hotspot-dev-request at openjdk.java.net>wrote:

>
>
> Message: 6
> Date: Tue, 08 Apr 2014 13:33:22 +0400
> From: Aleksey Shipilev <aleksey.shipilev at oracle.com>
> To: Cleber Muramoto <cleber at nightcoders.com.br>,
>         hotspot-dev at openjdk.java.net
> Subject: Re: JDK 8 great performance increase on ByteBuffer read
>         performance!?
> Message-ID: <5343C262.3080403 at oracle.com>
> Content-Type: text/plain; charset=ISO-8859-1
>
> Hi Cleber,
>
> On 04/07/2014 07:15 PM, Cleber Muramoto wrote:
> > I have a microbenchmark that does millions of iterations serializing and
> > deserializing objects to/from ByteBuffers
>
> Care to share the benchmark code?
>
> -Aleksey.
>
>
>


More information about the hotspot-dev mailing list