What I am measuring in writeObject() and readObject() is: 1) For PB I only measure the writeDelimitedTo() and parseDelimitedFrom public class PojoUsingPB extends AbstractPojo implements Serializable { ... private void writeObject(java.io.ObjectOutputStream out) throws IOException { ... long start = System.nanoTime(); message.writeDelimitedTo(out); long end = System.nanoTime(); ... }
private void readObject(java.io.ObjectInputStream in) throws ClassNotFoundException, IOException { long start = System.nanoTime(); PojoMessage.Pojo message = PojoMessage.Pojo.parseDelimitedFrom (in); long end = System.nanoTime(); ... 2) In Java I measure the ObjectOutputStream.writeObject() and ObjectInputStream.readObject(): public class PojoUsingJava extends AbstractPojo implements Serializable { ... private void writeObject(java.io.ObjectOutputStream out) throws IOException { long start = System.nanoTime(); out.writeObject(key); out.writeObject(value); out.writeBoolean(someBoolean); long end = System.nanoTime(); ... } private void readObject(java.io.ObjectInputStream in) throws ClassNotFoundException, IOException { long start = System.nanoTime(); key = (String) in.readObject(); value = (String) in.readObject(); someBoolean = in.readBoolean(); long end = System.nanoTime(); ... I don't know where I could have done something wrong. The results I am getting is: Duration using Java > Protocol Buffers Average remote time = 111309 > 122173 nanosecs Average serialization time = 3609 > 6586 nanosecs Average de-serialization time = 3533 > 9287 nanosecs Based on that PB seems to be slower and I am not coming to the same conclusion as stated in other performance tests?! Tai On Aug 17, 11:24 pm, Kenton Varda <ken...@google.com> wrote: > A message with three primitive fields should only take a couple hundred > nanoseconds to parse or serialize, unless the strings are *huge*. I have to > believe that something is wrong with the setup. > > On Mon, Aug 17, 2009 at 1:53 PM, Tai <maitai.tru...@gmail.com> wrote: > > > 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) { > > ... > > read more » --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---