Swoole 4.5.6支持零拷贝JSON或PHP反序列化

简介: 在最新的4.5.6开发分支中,底层增加了2个特殊的函数

在最新的4.5.6开发分支中,底层增加了2个特殊的函数:

  • swoole_substr_json_decode
  • swoole_substr_unserialize


这里为什么要增加这两个函数呢?有这样一种场景。使用Swoole\Server实现RPC服务,在EOF协议或长度协议通信方式下,一个包可能有3部分组成。


$packet = $header + $body + $footer

通常$header$footer比较小,而$body比较大,$body可能会使用JSONPHP序列化格式。如果要解析$body数据,那么就需要先进行substr得到$body的字符串格式数据,再进行json_decodeunserialize操作。

这会引起一次内存拷贝,$body_str = substr($packet, $header_length)的过程会创建一个临时字符串变量,再反序列化操作$body = json_decode($body_str)之后,这个变量就会被释放。


// 先进行 substr,这时会产生内存拷贝,从 $packet 复制数据到 $body_str
$body_str = substr($packet, 4, strlen($packet) - 4 - 2);
// 反序列化之后 $body_str 这块内存不再使用,会在函数退出时释放
$body = json_decode($body_str, true);

使用新增的两个函数就可以将substr反序列化操作合二为一。减少一次内存拷贝,从而提高性能。

$body = swoole_substr_json_decode($packet, $header_length);
$body = swoole_substr_unserialize($packet, $header_length);

压测


<?php
error_reporting(E_ALL);
$a['hello'] = base64_encode(random_bytes(1000));
$a['world'] = 'hello';
$a['int'] = rand(1, 999999);
$a['list'] = ['a,', 'b', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'];
$val = serialize($a);
$str = pack('N', strlen($val)).$val."\r\n";
$n = 100000;
$s = microtime(true);
while($n--) {
    $l = strlen($str) - 6;
    // var_dump(unserialize(substr($str, 4, $l)));
    var_dump(swoole_substr_unserialize($str, 4, $l));
}
echo "cost: ".(microtime(true)-$s)."n";

使用swoole_substr_unserializesubstr + unserialize相比,性能提升了12%


htf@htf-ThinkPad-T470p:~/workspace/debug$ php s.php
cost: 2.2559139728546
htf@htf-ThinkPad-T470p:~/workspace/debug$ php s.php
cost: 1.9821600914001
目录
相关文章
|
3月前
|
JSON PHP 数据格式
|
14天前
|
安全 PHP
PHP反序列化--_wakeup()绕过
PHP反序列化--_wakeup()绕过
|
1月前
|
JSON Java Maven
使用Jackson进行 JSON 序列化和反序列化
使用Jackson进行 JSON 序列化和反序列化
25 0
|
1月前
|
存储 JSON 安全
序列化模块pickle和json有什么区别
序列化模块pickle和json有什么区别
18 0
|
1月前
|
JSON JavaScript PHP
PHP把unicode编码的json字符串转中文
PHP把unicode编码的json字符串转中文
13 0
|
2月前
|
JSON 数据格式 C++
[序列化协议] --- JSON
[序列化协议] --- JSON
31 0
|
3月前
|
JSON PHP 数据格式
|
3月前
|
JSON PHP 数据格式
php 删掉空的数组 json数据. 空数据(false 0 ““ null)
php 删掉空的数组 json数据. 空数据(false 0 ““ null)
php 删掉空的数组 json数据. 空数据(false 0 ““ null)
|
3月前
|
JSON PHP 数据格式
php对‘[{“id“:“1“,“name“:“cyg”},{“id“:“2“,“name“:“liwen“}]json数据进行修改删除操作
php对‘[{“id“:“1“,“name“:“cyg”},{“id“:“2“,“name“:“liwen“}]json数据进行修改删除操作
php对‘[{“id“:“1“,“name“:“cyg”},{“id“:“2“,“name“:“liwen“}]json数据进行修改删除操作