英文:
JSON is way faster than Protobuf/gRPC for me, with Go as the server and PHP as the client
问题
也许我对Protobuf有些误解,但我花了一些时间来实现它,因为我希望相比于我目前的JSON设置,能够获得更快的速度。
我的使用情况是这样的:一个庞大而复杂的PHP应用程序(不是网站),正在生产中并且被广泛使用。我们现在正在尝试将我们的应用程序拆分为较小的部分,每个问题都使用适合的语言进行编写。我首先拆分出来的服务是对字符串进行处理和转换的,非常特定领域的且不太有趣。涉及大量的正则表达式、自定义解析等。
我在Go中实现了我的领域逻辑,它工作得很好,并且非常容易上手。我将我的逻辑附加到了一个简单的JSON API上,使用了Go-Kit。这是一个非常简单的转换,将JSON编码简单地转换为类似于{"v":"一些字符串,通常是10-100个字符"}的形式。
性能比原生的PHP要差,考虑到JSON的开销以及通过网络层传输的额外开销,我认为这是可以接受的。
然而,真正让我惊讶的是,Protobuf不仅没有比JSON更快,而且实际上比JSON慢了30-50%。
我的.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;
}
我使用了https://github.com/stanley-cheung/Protobuf-PHP和生成的proto php代码。我的php客户端代码如下:
$client = new StringClient('localhost:50051', [
'credentials' => \Grpc\ChannelCredentials::createInsecure()]);
$string = new StringReq();
$string->setIn("some string...");
list($reply, $status) = $client->DoStringStuff($string)->wait();
它可以工作,但令我惊讶的是它比JSON要慢得多。
我唯一的猜测是:可能PHP的Protobuf实现比json_decode慢得多,以至于目前PHP对于Protobuf来说是一个非常糟糕的客户端?
或者对于像传输单个字符串这样的小而简单的用途,JSON应该比Protobuf表现更好吗?
谢谢你的所有想法。
英文:
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.
答案1
得分: 5
protobuf
的原生PHP实现,你可以通过composer require google/protobuf
来安装,但它的速度比protobuf C扩展要慢得多。要获得真正的gRPC性能,你需要安装protobuf C扩展:
pecl install protobuf
并在php.ini
中启用它:
extension=protobuf.so
这样做会将所有的序列化/反序列化操作都在C语言中进行,而不是在PHP中进行,因此速度会比PHP版本快很多倍。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论