PHP5.5四種序列化效能對比
阿新 • • 發佈:2019-01-23
json_encode,serialize,igbinary,msgpack四種序列化方式,在之前已經有過相關的測試,PHP5.5這方面的測試暫時沒有,這次測試基於PHP5.5,並且測試用例,
的測試用例是一樣的,只是從這個測試上家裡igbinary serialize的測試,作為對比,可以參考
http://www.ooso.net/archives/538
執行環境
PHP5.5 記憶體 16G 8核 2.0GMHz
效能&空間大小列表
採用小陣列測試結果(注意為了資料好看,小陣列測試時,迴圈次數為10000次,大陣列為1000次)
json :156 serialize :222 igbinary_serialize :123 msgpack :102 json_encode :0.22339701652527 json_decode :0.53043985366821 serialize :0.31040406227112 unserialize :0.30859398841858 Igbinary Serialize: 0.25647687911987 Igbinary unSerialize: 0.19416117668152 msgpack_pack: 0.14058780670166 msgpack_unpack: 0.29048585891724
方便對比把之前PHP5.3的測試結果放到下面(之前並未測試igbinary)
json :156
serialize :222
json_encode :0.1087498664856
json_decode :0.12652111053467
serialize :0.041656017303467
unserialize :0.040987968444824
採用大陣列測試結果
json :5350 serialize :8590 igbinary_serialize :2432 msgpack :3929 json_encode :0.92437314987183 json_decode :1.791629076004 serialize :1.3011419773102 unserialize :1.1485421657562 Igbinary Serialize: 0.90479803085327 Igbinary unSerialize: 0.69125699996948 msgpack_pack: 0.52022004127502 msgpack_unpack: 1.0104610919952
下面是之前的結果(之前並未測試igbinary)
json :5350
serialize :8590
json_encode :0.90479207038879
json_decode :1.753741979599
serialize :1.3566699028015
unserialize :1.3003630638123
小結:
資料方面:
1:升級到PHP5.5後,json,serialize,igbinary三種方式序列化後,大小沒有變化,說明這三種格式的物件結構沒有沒有變化,所以可以無縫升級,msgpack由於沒有之前的資料做對比,暫時未知。
2:佔用空間方面,igbinary節省空間明顯優勢,比如在json一個數組5.4k大小的資料,serialize方式要8.6k,而使用igbinary方式,僅需2.4k,近乎為serialize方式的1/4,但在小陣列方面msgpack方式更具優勢,igbinary佔用空間123,而msgpack方式僅為102。但是在大陣列情況下,明顯igbinary方式優勢更明顯。大陣列igbinary勝出,小陣列msgpack勝出。
效能方面:
2:在序列化方面,msgpack方式效能最好,其次是json_encode的,再次是igbinary,這兩者相差無幾,最差的為原生serialize,原生serialize效能消耗大概為json和igbinary方式的的1.4倍左右,而是msgpack方式的2倍。在大陣列方面,序列化方便,基本上和小陣列一致,只是igbinary效能教較json_encode方式有所提升。本輪msgpack勝出。
3:在反序列方面igbinary的比序列化過程更快,當然也是最快的,但是這種快也是有成本代價的,參見最後的注意事項,最慢的為json_decode方式,猜測原因可能在於PHP作為伺服器端應用,最多的場景是encode,而decode的最常見的為js處理方式,效能不是很理想。而msgpack反序列化效能基本上是它序列化的2倍。本輪igbinary勝出。
4:整體效能對比,整體效能是序列化和反序列化之和,簡單對比會發現,json是最差的,次之是原生serialize,再次為igbinary的方式,最優的為msgpack,不過igbinary和msgpack相差真的非常小,而在佔用空間方面,小資料時msgpack勝出,大資料時igbinary勝出,算是各有千秋。所以,如果追求極致的效能,可以考慮使用msgpack,如果對是使用空間要求苛刻,那就選擇igbinary方式,估計這也是PHPRedis選擇igbinary作為內建序列化方式的原因之一,另外還有一個原因,考慮到Redis應用場景多是一寫多讀,要保證反序列化效能足夠高,非igbinary莫屬。
使用igbinary並非沒有代價,在測試中我們發現,呼叫igbinary_unserialize時,傳遞非法資料,會導致整個php程序死掉,日誌
child 19131 exited on signal 11 (SIGSEGV) after 1.844938 seconds from start 1.844938 seconds from start
估計是因為igbinary為了提升效能,在unserialize時,沒有做相關格式驗證,導致整個程序異常退出。在使用Redis時,我們先期使用SERIALIZE_PHP方式序列化,為了提升效能,減少對Redis空間的浪費採用igbinary_serialize方式,再切換的時候不小心踩到這個坑,導致伺服器響應出錯,直接502,幸虧在daily環境上。