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

标签 go protocol-buffers grpc

也许我有点忽略了 Protobufs 的意义,但我花了一些时间来实现它,因为与我当前的 JSON 设置相比,我希望获得原始速度。

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

我在 Go 中实现了我的域逻辑,它工作得很好并且很容易上手。我使用 Go-Kit 将我的逻辑附加到一个简单的 JSON API。是一个非常简单的转换,json 编码简单到类似 {"v":"some string usually 10-100 chars"}。

性能比原生 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和生成的原始 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 执行得更好吗?

感谢您的所有想法。

最佳答案

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

pecl install protobuf

并在php.ini中启用它

extension=protobuf.so

所有的序列化/反序列化都是在 C 语言中完成的,而不是在 PHP 中,后者比 PHP 版本快很多倍。

关于go - JSON 对我来说比 Protobuf/gRPC 快得多,Go 作为服务器,PHP 作为客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41839443/

相关文章:

function - 在 Go 模板中,我可以让 Parse 工作但不能让 ParseFiles 以类似的方式工作。为什么?

dictionary - 在一种情况下检查键是否存在于多个映射中

javascript - ProtoBuf.js 如何在编码对象时过滤额外字段

Golang amqp 重新连接

c++ - 如何在不复制 C++ 的情况下分配嵌套的 protobuf?

go - 返回消息列表

go - RegisterService 和处理程序方法未生成 gRPC 和 go

c# - 将类从一个 C# 项目导入到另一个项目时是否可以排除自动生成的文件?

docker - Google Cloud ESP 向 gRPC 服务器通告无效的压缩格式

mysql - 根据 slice Go中的键顺序对数据进行排序