在最新的4.5.6
开发分支中,底层减少了2
个非凡的函数:
swoole_substr_json_decode
swoole_substr_unserialize
这里为什么要减少这两个函数呢?有这样一种场景。应用Swoole\Server
实现RPC
服务,在EOF
协定或长度协定通信形式下,一个包可能有3
局部组成。
$packet = $header + $body + $footer
通常$header
和$footer
比拟小,而$body
比拟大,$body
可能会应用JSON
或PHP
序列化格局。如果要解析$body
数据,那么就须要先进行substr
失去$body
的字符串格局数据,再进行json_decode
和unserialize
操作。
这会引起一次内存拷贝,$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);
压测
<?phperror_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."rn";$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_unserialize
与substr + unserialize
相比,性能晋升了12%
htf@htf-ThinkPad-T470p:~/workspace/debug$ php s.phpcost: 2.2559139728546htf@htf-ThinkPad-T470p:~/workspace/debug$ php s.phpcost: 1.9821600914001