对我来说,JSON比Protobuf / gRPC更快,Go作为服务器,PHP作为客户端

时间:2017-01-24 21:38:33

标签: go protocol-buffers grpc

也许我有点错过了Protobufs的观点,但我花了一些时间来实现它,因为我希望获得原始速度,而不是我目前的JSON设置。

我的用例是这样的:一个庞大而复杂的PHP应用程序(不是一个网站),在生产中并被大量使用。我们现在正试图将我们的应用程序分成更小的部分,用适当的语言编写每个问题。我拆分的第一个服务是对字符串进行处理和转换,非常特定于域并且不是很有趣。涉及许多正则表达式,自定义解析等。

我在Go中实现了我的域逻辑,它工作得很漂亮,很容易上手。我使用Go-Kit将我的逻辑附加到一个简单的JSON API。是一个非常简单的转换,json编码简单到类似{“v”:“一些字符串通常是10-100个字符”}。

性能比本机PHP差,考虑到JSON的开销和通过网络层添加传输,我认为这是完全可以接受的。

然而,让我感到惊讶的是,Protobuf不仅没有比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慢很多。

我唯一的猜测:Protobufs的php实现是否可能比json_decode慢得多,目前PHP为Protobuf做了一个非常糟糕的客户端?

对于小型简单用途,例如传输JSON应该执行Protobuf的单个字符串,这是正常的吗?

感谢您的任何想法。

1 个答案:

答案 0 :(得分:2)

使用protobuf安装的composer require google/protobuf的本机PHP实现protobuf C extension慢得多。要从gRPC中获得任何真正的性能,您需要安装protobuf C扩展:

pecl install protobuf

并在php.ini

中启用它
extension=protobuf.so

这在C中进行所有序列化/反序列化而不是PHP,这比PHP版本快许多倍。