20

最近在观看swoole官方的课程时,其中有一小段专门说到了json_decode这个函数的效率问题,其慢的原因是在进行转化时需要遍历文中每一个字符去寻找EOF(end of file:文字流的结尾,关于EOF阮一峰大神这篇文章解释得很详细),而只有在确认整个字符串的格式和长度后,json格式才可以被decode,也就是说假设整个字符串的长度为N,那程序就必须进行N+1次的遍历,那如果对于一些高并发的场景时,是否有更好的解决办法呢?

关于序列化还有另外一个常用的函数就是serialize,serialize在序列化后会将数值的类型和长度都一一记录在序列化后的字符串中,如果依照这个思路,serialize在进行反序列化时应该可以依照之前生成的字符直接去进行格式化,而无需再进行全文的遍历寻找EOF,那是否在长字符串的情况下unserialize会比json_decode效率更高呢?

于是做了如下的实验,分别用了三种类型的数组数据作为测试,别为中文,英文,以及数字,进行一次序列化和反序列化为一个循环进行测试,其中基数为循环的次数:

$array = [
    "I'm a gooPHP 是免费的,并且使用非常广泛。同时,对于像微软 ASP 这样的竞争者来说,PHP 无疑是另一种高效率的选项。PHP 极其适合网站开发,其代码可以直接嵌入 HTML 代码.",
    "I'm a good boy.",
    "a" => "PHP 是免费的,并且使用非常广泛。同时,对于像微软 ASP 这样的竞争者来说,PHP 无疑是另一种高效率的选项。PHP 极其适合网站开发,其代码可以直接嵌入 HTML 代码",
    2 =>"PHP 是免费的,并且使用非常广泛。同时,对于像微软 ASP 这样的竞争者来说,PHP 无疑是另一种高效率的选项。PHP 极其适合网站开发,其代码可以直接嵌入 HTML 代码",
    'PHP 是免费的,并且使用非常广泛。同时,对于像微软 ASP 这样的竞争者来说,PHP 无疑是另一种高效率的选项。PHP 极其适合网站开发,其代码可以直接嵌入 HTML 代码',
    "I'm a good boy.",
    "I'm a good boy.",
    "I'm a good boy.",
    "I'm a good boy.",
    "I'm a good",
    "asdfnsadofhasd"];
$array = [
    "I'm a boy",
    "I'm a boy",
    "I'm a boy",
    "I'm a boy",
    "I'm a boy",
    "I'm a boy",
    "I'm a boy",
    "I'm a boy",
    "I'm a boy",
    "I'm a boy",
];
$array = [
    0 => 9115,
    1 => 9115,
    2 => 9115,
    3 => 9115,
    4 => 9115,
    5 => 9115,
    6 => 9115,
    7 => 9115,
    8 => 9115,
    9 => 9115,
];

得出的测试结果如下
TIM图片20191021163119.png

可以看到在英文和数字的序列化中,json的序列化效率是serialize的2-3倍,而在中文数组的测试中,serialize的效率为json的8-10倍,也印证了前面的猜测:json在序列化和反序列数据时,字符串长度越长,cpu需要去执行寻找EOF的次数便越多,而serialize因为在序列化的时候便记录了字符串的长度,所以在反序列化的时候会比json花更少的时间

但serialize也有其自身的不足:
1.因为在序列化时记录了对应的字符串的长度和类型,所以在相同的数据下,serialize会比json更占用空间,用空间换取了时间。
2.serialize序列化后的内容对比起json可读性较差,在进行问题排查时相对麻烦一些。

看到这里大家应该明白这两种序列化的适用场景:
如果是短内容的场景下,使用json作序列化是比较好的方法,不仅效率高且更字符串体积更小
如果是在长字符串的场景下,可以考虑用serialize,程序的执行效率会比json高不少!

文末附上swoole课堂的地址,满满的干货:https://course.swoole-cloud.com/course-video/52


陈小楷
185 声望7 粉丝