I have now also tried parseDelimitedFrom() and writeDelimitedTo. The
performance difference is still by a factor of almost 2:

Average Java time: 154333 nanosecs
Average PB time: 293566 nanosecs

Average Java time: 149934 nanosecs
Average PB time: 275076 nanosecs

I will try with a bigger message but I doubt that PB will get any
close to Java's total performance (serialization, deserialization and
object creation).

I was hoping to give our RMI environment a boost but I doesn't look
like this. I will give it another chance.

Tai


On 17 Aug., 22:07, Kenton Varda <ken...@google.com> wrote:
> Oops, I missed it when skimming.
>
> >       PojoMessage.Pojo message = PojoMessage.Pojo.parseFrom(in);
>
> That line won't work.  Protocol buffers are not self-delimiting, so
> parseFrom() -- if it succeeds -- always reads the *entire* input.  You
> should use parseDelimitedFrom() instead, and use writeDelimitedTo() on the
> sending side.
>
> BTW, with such a small message, the cost of serializing and parsing the
> message is going to be extremely small compared to the cost of the RPC
> system, network time, etc.  I'd be pretty surprised if there is any
> significant difference between the two approaches.
>
> On Mon, Aug 17, 2009 at 12:48 PM, Tai <maitai.tru...@gmail.com> wrote:
>
> > I am using 2.1.0 and as shown above the proto file uses option
> > optimize_for = SPEED;
>
> > On Aug 17, 8:56 pm, Kenton Varda <ken...@google.com> wrote:
> > > What version of protocol buffers are you using?  If it's 2.0.3 or
> > previous
> > > then you need to put this line in your proto files:
> > >   option optimize_for = SPEED;
>
> > > In 2.1.0 and up, this is the default.
>
> > > On Mon, Aug 17, 2009 at 10:29 AM, Tai <maitai.tru...@gmail.com> wrote:
>
> > > > Hi,
>
> > > > I did some simple test to compare Java vs. ProtocolBuffers. I know
> > > > that there is already a very verbose benchmark measuring
> > > > serialization, object creation and de-serialization here:
> > > >http://www.eishay.com/2009/03/more-on-benchmarking-java-serialization.
> > ..
>
> > > > But when using RMI I am getting a total time where PB is slower than
> > > > Java. My performance test measures the total time when passing a Pojo
> > > > from a client to a remote agent. The results I get when running the
> > > > tests twice are:
> > > > Average Java time: 147421 nanosecs
> > > > Average PB time: 281617 nanosecs (factor 1.91 slower)
>
> > > > Average Java time: 232446 nanosecs
> > > > Average PB time: 467485 nanosecs (factor 2.01 slower)
>
> > > > I was expecting PB to be faster than Java?! But this seems to be
> > > > wrong.
>
> > > > My classes are (unfortunately I cannot attach to the source / you can
> > > > email me if you want a zip):
>
> > > > The rmi interface for the agent server:
> > > > =========================================================
> > > > package test.protocolbuffers;
>
> > > > import java.rmi.Remote;
> > > > import java.rmi.RemoteException;
>
> > > > public interface IRemoteAgent extends Remote {
>
> > > >    long doSomething(long start, Object pojo) throws RemoteException;
>
> > > > }
> > > > =========================================================
>
> > > > The server agent implementing the interface
> > > > =========================================================
> > > > package test.protocolbuffers;
>
> > > > import java.rmi.RemoteException;
> > > > import java.rmi.registry.LocateRegistry;
> > > > import java.rmi.registry.Registry;
> > > > import java.rmi.server.UnicastRemoteObject;
>
> > > > public class RemoteAgent implements IRemoteAgent {
>
> > > >    public RemoteAgent() {
> > > >    }
>
> > > >    public static void main(String[] args) throws Exception {
> > > >        RemoteAgent agent = new RemoteAgent();
> > > >        String name = "RemoteAgent1";
> > > >        UnicastRemoteObject.exportObject(agent, 0);
> > > >        Registry registry;
> > > >        try {
> > > >            registry = LocateRegistry.createRegistry(1099);
> > > >        } catch (Exception e) {
> > > >            registry = LocateRegistry.getRegistry();
> > > >        }
> > > >        registry.rebind(name, agent);
> > > >        System.out.println(name + " bound.");
>
> > > >    }
>
> > > >    public long doSomething(long start, Object pojo) throws
> > > > RemoteException {
> > > >        long end = System.nanoTime();
> > > >        return end - start;
> > > >    }
> > > > }
> > > > =========================================================
>
> > > > The Java POJO for measuring the using standard Java serialization:
> > > > =========================================================
> > > > package test.protocolbuffers;
>
> > > > import java.io.Serializable;
>
> > > > public class PojoUsingJava implements Serializable {
> > > >    private String key;
> > > >    private String value;
> > > >    private boolean someBoolean;
>
> > > >    public PojoUsingJava(String key, String value, boolean
> > > > someBoolean) {
> > > >        this.key = key;
> > > >        this.value = value;
> > > >        this.someBoolean = someBoolean;
> > > >    }
>
> > > > }
> > > > =========================================================
>
> > > > The PB Pojo:
> > > > =========================================================
> > > > package test.protocolbuffers;
>
> > > > import java.io.IOException;
> > > > import java.io.Serializable;
> > > > import test.protocolbuffers.PojoMessage.Pojo.Builder;
>
> > > > public class PojoUsingPB implements Serializable {
> > > >    private String key;
> > > >    private String value;
> > > >    private boolean someBoolean;
>
> > > >    public PojoUsingPB(String key, String value, boolean someBoolean)
> > > > {
> > > >        this.key = key;
> > > >        this.value = value;
> > > >        this.someBoolean = someBoolean;
> > > >    }
>
> > > >    private void writeObject(java.io.ObjectOutputStream out) throws
> > > > IOException {
> > > >        Builder builder = PojoMessage.Pojo.newBuilder();
> > > >        builder.setKey(key);
> > > >        builder.setValue(value);
> > > >        builder.setSomeBoolean(someBoolean);
> > > >        PojoMessage.Pojo message = builder.build();
> > > >        message.writeTo(out);
> > > >    }
>
> > > >    private void readObject(java.io.ObjectInputStream in)
> > > >            throws ClassNotFoundException, IOException {
> > > >        PojoMessage.Pojo message = PojoMessage.Pojo.parseFrom(in);
> > > >        key = message.getKey();
> > > >        value = message.getValue();
> > > >        someBoolean = message.getSomeBoolean();
> > > >    }
>
> > > > }
> > > > =========================================================
>
> > > > The proto file being used in the PB Pojo:
> > > > =========================================================
> > > > package test.protocolbuffers;
>
> > > > option optimize_for = SPEED;
>
> > > > message Pojo {
>
> > > >    optional string key = 1;
> > > >    optional string value = 2;
> > > >    optional bool someBoolean = 3;
> > > > }=========================================================
>
> > > > The test class for measuring the remote calls using Java and PB:
> > > > =========================================================
> > > > package test.protocolbuffers;
>
> > > > import java.rmi.registry.LocateRegistry;
> > > > import java.rmi.registry.Registry;
>
> > > > public class RemoteProtoPerfTest {
>
> > > >    public static void main(String[] args) throws Exception {
> > > >        //get the remote agent
> > > >        Registry registry = LocateRegistry.getRegistry(1099);
> > > >        IRemoteAgent remoteAgent = (IRemoteAgent) registry.lookup
> > > > ("RemoteAgent1");
> > > >        // warm up
> > > >        for (int i = 0; i < 100; i++) {
> > > >            remoteAgent.doSomething(System.nanoTime(), "warmup");
> > > >        }
> > > >        int calls = 1000;
>
> > > >        //measure the total time (serialization, network
> > > > transportation, deserialization)
> > > >        //using java serialization
> > > >        long totalJavaDuration = 0;
> > > >        PojoUsingJava pojoUsingJava = new PojoUsingJava("key",
> > > > "value", false);
> > > >        for (int i = 0; i < calls; i++) {
> > > >            if ( i % 200 == 0) {
> > > >                System.out.println("Loop: " + i);
> > > >            }
> > > >            totalJavaDuration += remoteAgent.doSomething
> > > > (System.nanoTime(), pojoUsingJava);
> > > >        }
> > > >        totalJavaDuration /= calls;
> > > >        System.out.println("Average Java time: " + totalJavaDuration +
> > > > " nanosecs");
>
> > > >        //measure the total time (serialization, network
> > > > transportation, deserialization)
> > > >        //using Protocol Buffers
> > > >        long totalPbDuration = 0;
> > > >        PojoUsingPB pojoUsingPB = new PojoUsingPB("key", "value",
> > > > false);
> > > >        for (int i = 0; i < calls; i++) {
> > > >            if ( i % 200 == 0) {
> > > >                System.out.println("Loop: " + i);
> > > >            }
> > > >            totalPbDuration += remoteAgent.doSomething(System.nanoTime
> > > > (), pojoUsingPB);
> > > >        }
> > > >        totalPbDuration /= calls;
> > > >        System.out.println("Average PB time: " + totalPbDuration + "
> > > > nanosecs");
>
> > > >    }
>
> > > > }
> > > > =========================================================
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To post to this group, send email to protobuf@googlegroups.com
To unsubscribe from this group, send email to 
protobuf+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/protobuf?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to