Reputation: 79
Perhaps I've somewhat missed the point of Protobufs, but I spent some time to implement it because I was hoping to gain raw speed compared to my current JSON setup.
My use case is like this: a large, complicated PHP application (not a website), in production and being used heavily. We're now trying to split our application into smaller parts, written in a suitable language for each problem. The first service I have split out does processing and transformations on strings, very domain specific and not very interesting. Involves lots of regex's, custom parsing etc.
I implemented my domain logic in Go, which works beautifully and was very easy to pick up. I attached my logic to a simple JSON API, using Go-Kit. Is a very simple transformation, json encoding simply to something like {"v":"some string usually 10-100 chars"}.
The performance was worse than native PHP which I consider quite acceptable considering the overhead of JSON and the addition of transmitting over a network layer.
However, what really surprised me is that Protobuf has not only been no faster than JSON, but actually slower by 30-50%.
My .proto:
syntax = "proto3";
package pb;
option optimize_for = SPEED;
service StringStuff {
rpc DoStringStuff (StringReq) returns (StringRes) {}
}
message StringReq {
string in = 1;
}
message StringRes {
string out = 1;
}
I used https://github.com/stanley-cheung/Protobuf-PHP and the generated proto php code. My php client code is like this:
$client = new StringClient('localhost:50051', [
'credentials' => \Grpc\ChannelCredentials::createInsecure()]);
$string = new StringReq();
$string->setIn("some string...");
list($reply, $status) = $client->DoStringStuff($string)->wait();
It works but to my surprise it is a lot slower than JSON.
My only guess: is it possible the php implementation of Protobufs is so much slower than json_decode that currently PHP makes a very poor client for Protobuf?
Or is it normal for small, simple uses like transmitting a single string that JSON should out perform Protobuf?
Thank you for any and all thoughts.
Upvotes: 4
Views: 3224
Reputation: 501
The native PHP implementation of protobuf
, which you install with composer require google/protobuf
is much slower than the protobuf C extension. To get any real performance out of gRPC you need to install the protobuf C extension:
pecl install protobuf
and enable it in php.ini
extension=protobuf.so
This does all the serialization/deserialization in C rather than in PHP, which going to be many times faster than the PHP version.
Upvotes: 5