2017-01-24 20 views
2

Возможно, я несколько упустил точку Protobufs, но я потратил некоторое время на ее реализацию, потому что я надеялся получить сырую по сравнению с моей текущей установкой JSON.JSON быстрее, чем Protobuf/gRPC для меня, с Go в качестве сервера и PHP в качестве клиента

Мой вариант использования такой: большое, сложное приложение PHP (а не веб-сайт), в производстве и используется в значительной степени. Теперь мы пытаемся разбить наше приложение на более мелкие части, написанные на подходящем языке для каждой проблемы. Первая служба, которую я разделил, обрабатывает и преобразует строки, очень специфичные для домена и не очень интересные. Привлекает много регулярных выражений, пользовательский синтаксический анализ и т. Д.

Я реализовал свою логику домена в Go, которая работает красиво и очень легко подобрать. Я приложил свою логику к простому JSON API, используя Go-Kit. Это очень простая трансформация, 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 и сгенерированный прото код 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 Protobufs намного медленнее, чем json_decode, что в настоящее время PHP делает очень плохой клиент для Protobuf?

Или это нормально для небольших простых применений, таких как передача одной строки, которую JSON должен выполнить Protobuf?

Спасибо за любые мысли.

+0

Это [большая библиотека] (https://github.com/stanley-cheung/Protobuf-PHP/), написанная на PHP, а 'json_encode' написана на C++ и была использована миллионами и оптимизирована с момента первого добавления , 'json_encode' будет во много раз быстрее, чем любая система упаковки на основе PHP. – Xeoncross

+0

Спасибо, это была моя догадка, и это имеет большой смысл. Взвешивание плюсов и минусов Protobufs более сложно, потому что в конце концов PHP не будет единственным клиентом. Из вашего опыта есть ли более быстрый способ передачи в этом конкретном прецеденте, чем JSON? – mhsc

+0

BSON более компактен и используется несколькими двигателями баз данных. Хотя это просто двоичный JSON, поэтому не поддерживает схемы вроде Protobufs. – Xeoncross

ответ

2

Уроженец реализация PHP из protobuf, который устанавливается с composer require google/protobuf является гораздо медленнее, чемprotobuf C extension. Для того, чтобы получить какой-либо реальной производительности из КПГР вам необходимо установить расширение Protobuf C:

pecl install protobuf 

и включить его в php.ini

extension=protobuf.so 

Это делает все сериализации/десериализации в C, а не в PHP, который будет во много раз быстрее, чем версия PHP.