數據的序列化是一個很是有用的功能,然而目測不少人跟我同樣,在剛接觸這玩意的時候壓根就不理解這貨色究竟是幹啥用的,反正老師說了,實在理解不了就先背過再說。php
「啥犢子玩意啊,又是序列化、又是反序列化。。。」(圖片來自於《個人團長個人團》之國軍二道販子兼二人轉演員迷龍同窗)。html
其實將數據序列化的做用無外乎有兩個:前端
方便存儲如何理解呢?好比咱們有個PHP對象或者一個PHP數組須要存儲到數據庫甚至文件中,這顯然是不可能的,這個時候必需要將PHP對象或者PHP數組序列化後再執行存儲操做。不過這將PHP數組序列化後存起來還能理解,這對象也能存儲啊?這操做是否過於風騷?少年,這一點兒都不風騷。有些時候將對象直接存儲起來,用的時候只須要簡單的反序列化後就能夠投產使用了,避免了new一次帶來的性能耗費。node
方便傳輸如何理解呢?其實序列化在傳輸中應用的相對更多更常見些許。最簡單的一個例子,一個碼前端的碼了一個ajax找你給TA提供一個API,那麼這個時候你倆得商量返回什麼數據,好比json或者xml,甚至你倆本身做死約定私有數據格式。好比在一個比較典型的服務架構中,網關服務器和內部RPC服務器之間經過msgpack傳遞數據。這都是典型的序列化爲了傳輸的典型應用案例。ajax
這裏序列化的概念可能更爲普遍和籠統一些,包括傳統的serialize、json、msgpack、protobuf等。( 若是你以爲序列化這個稱呼不太嚴謹的話,能夠用encode來代替;反序列化則用decode來代替。反正我就用通通用序列化和反序列化來稱呼了,若是你以爲實在不舒服,能夠順着網線來砍我!)。數據庫
實際上,從更高的層面看,數據的序列化能夠分爲兩種:json
通常說來,考驗序列化技術的性能指標一共有兩個,一個是序列化的速度,一個是序列化後數據的大小,天然是序列化速度越快、序列化後的數據越小爲佳。就目前來看,protobuf、msgpack等二進制序列化不管是速度上仍是數據大小上,都要比文本序列化更好。不過話說回來,文本序列化有更好的可讀性,一眼就能瞪出來數據內容大概是啥玩意。數組
今天帶到這裏的這裏的有四個具體的方案,這四種方案都是簡單粗暴、開箱即用類型的,咱們分別測試感覺下,看哪一個更適合咱們。服務器
參會的四個哥們:PHP內置的serialize、PHP內置的JSON解析器、PHP擴展JSOND、PHP擴展msgpack。其中前三個都是文本類型的,msgpack則是二進制類型的。架構
JSOND做爲PHP內置的JSON解析器的高級版本,坊間一直傳聞速度上要比內置的更牛X一些,做爲擴展,這貨須要額外安裝,附送地址:https://pecl.php.net/get/json...。
msgpack是一個鳥哥等人搞的一套二進制序列化工具,slogan就是「It's like JSON.but fast and small.」,附送地址:https://pecl.php.net/get/msgp...
測試代碼以下:
<?php // 故意搞了一個還算大的php數組,更容易看出差距來 $arr = array( array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), 'relation' => array( array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), array( 'uid' => 22193123, 'gender' => 'famale', 'username' => 'elarity', 'password' => md5('www123'), ), ), ) ); // 每種序列化方案都執行100000次 $counter = 100000; // json序列化方案,執行100000次 echo PHP_EOL.PHP_EOL; $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $json = json_encode( $arr ); } $size = strlen( $json ); $end = microtime( true ); $cost_time = $end - $start; echo "json_encode : 耗費時間爲{$cost_time} , 數據體積爲{$size}".PHP_EOL; // jsond序列化方案,執行100000次 $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $jsond = jsond_encode( $arr ); } $size = strlen( $jsond ); $end = microtime( true ); $cost_time = $end - $start; echo "jsond_encode : 耗費時間爲{$cost_time} , 數據體積爲{$size}".PHP_EOL; // serialize序列化方案,執行100000次 $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $serialize = serialize( $arr ); } $size = strlen( $serialize ); $end = microtime( true ); $cost_time = $end - $start; echo "serialize : 耗費時間爲{$cost_time} , 數據體積爲{$size}".PHP_EOL; // msgpack序列化方案,執行100000次 $start = microtime( true ); for( $i = 1; $i <= $counter; $i++ ){ $msgpack = msgpack_pack( $arr ); } $size = strlen( $msgpack ); $end = microtime( true ); $cost_time = $end - $start; echo "msgpack耗費時間爲 : {$cost_time} , 數據體積爲{$size}".PHP_EOL; echo PHP_EOL.PHP_EOL;
將文件保存爲test.php,而後php test.php執行,結果以下圖所示:
總結一下:
「能夠看看個人測試:https://blog.yurunsoft.com/a/...我選擇的數據類別相對較多,有數組有對象,有小數據有較多的數據,其實固定地說哪一個更好更快,沒有意義,要根據實際場景選擇合適的纔好」