ruby-protobuf, by MATSUYAMA Kengo (@macks_jp), was straightforward to install and use. It has a good online tutorial and the redme has all I needed to get started.
ruby-protocol-buffers, by Brian Palmer was also easy to install and use. It seems a bit lacking in the online documentation, but does have some examples to follow. (If Brian's name rings a bell, it might be because I interviewed him some time ago about winning a programming contest sponsored by Mozy's former incarnation.)
I started out with a very simple proto file:
package bench; message Person { required string name = 1; required int32 id = 2; optional string email = 3; }
I compiled this with
rprotoc
for ruby-protobuf and with ruby-protoc
for ruby-protocol-buffers. This generated the following (which I edited lightly). For ruby-protof:for ruby-protocol-buffer### Generated by rprotoc. DO NOT EDIT! ### <proto file: bench.proto> # package bench; # # message Person { # required string name = 1; # required int32 id = 2; # optional string email = 3; # } require 'protobuf/message/message' require 'protobuf/message/enum' require 'protobuf/message/service' require 'protobuf/message/extend' module Bench1 class Person1 < ::Protobuf::Message defined_in __FILE__ required :string, :name, 1 required :int32, :id, 2 optional :string, :email, 3 end end
#!/usr/bin/env ruby # Generated by the protocol buffer compiler. DO NOT EDIT! require 'protocol_buffers' # Reload support Object.__send__(:remove_const, :Bench2) if defined?(Bench2) module Bench2 # forward declarations class Person2 < ::ProtocolBuffers::Message; end class Person2 < ::ProtocolBuffers::Message required :string, :name, 1 required :int32, :id, 2 optional :string, :email, 3 gen_methods! # new fields ignored after this point end end
Then I pulled out the statistical benchmarking I wrote about a while ago (Since no one else has taken the bait, maybe I should bundle up a gem for that.). Instead of quoting the whole thing at you, here are the pertinent loops. For ruby-protobuf:
msg = Bench1::Person1.new(:name => idx.to_s, :id => idx, :email => idx.to_s) msg_str = msg.serialize_to_string msg == msg.parse_from_string(msg_str)
for ruby-protocol-buffer:
msg = Bench2::Person2.new(:name => idx.to_s,
:id => idx,
:email => idx.to_s)
msg == Bench2::Person2.parse(msg.to_s)
And here are the results:
$ rvm 1.9.2 $ ruby -v ruby 1.9.2p0 (2010-08-18 revision 29036) [i686-linux] $ time ruby ProtoBufBench testing ruby-protobuff against ruby-protocol-buffer The deviation in the deltas was 0.021731 The mean delta was 0.198301 max = 0.241761921640842 :: min = 0.154839326146633 ruby-protocol-buffer was better real 1m50.672s user 1m50.599s sys 0m0.092s $ rvm 1.8.7 $ ruby -v ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-linux] $ time ruby ProtoBufBench testing ruby-protobuff against ruby-protocol-buffer The deviation in the deltas was 0.009414 The mean delta was -2.205984 max = -2.18715483485056 :: min = -2.22481263341116 There's no statistical difference real 3m8.131s user 3m7.996s sys 0m0.056s
I didn't try compiling the c extension for ruby-protocol-buffers, and I haven't tried any more involved .proto files yet. I'll work on those in the next couple of days and post results as I see them.
7 comments:
I'd definitely recommend using the java protobuf stuff from JRuby. It works really well and the performance is going to be dramatically better. We've been doing a lot of this lately and we're really happy with it.
@Clayton, thanks for the recommendation. I'll have to give that a try.
Would be interesting to compare with beefcake as well.
@jarib, thanks for the pointer to beefcake. I'll be checking it out.
Have you try compiling the c extension for ruby-protocol-buffers?
I haven't tried the c-extension. Have you? What was your experience?
No I have not. I m trying to do somethin like this in ruby
node::Buffer::Data(val) node::Buffer::Length(val); node::Buffer::HasInstance(value)
Above code is in node.js for c extension. I am looking for any buffer class that I can use to do similar.
Post a Comment