存储起来会更有效吗?该文本文件中将数组作为JSON还是作为PHP序列化数组?我环顾四周,似乎在最新版本的PHP(5.3)中,
json_decode
实际上比unserialize
快。我目前倾向于将数组存储为JSON,因为我觉得它更容易要在需要时由人类阅读,可以非常轻松地在PHP和JavaScript中使用,并且根据我的阅读,解码甚至可能更快(尽管不确定编码)。
有人知道有什么陷阱吗?任何人都有良好的基准,可以证明这两种方法的性能优势?
#1 楼
取决于您的优先顺序。如果性能是您的绝对驱动特性,则一定要使用最快的驱动器。只需确保在做出选择之前就对差异有充分的了解
与
serialize()
不同,您需要添加额外的参数以保持UTF-8字符不变:json_encode($array, JSON_UNESCAPED_UNICODE)
(否则它将转换UTF -8个字符表示Unicode转义序列)。JSON将不存储该对象的原始类是什么(它们始终作为stdClass的实例还原)。
您不能在JSON中使用
__sleep()
和__wakeup()
默认情况下,仅公共属性使用JSON序列化。 (在
PHP>=5.4
中,您可以实现JsonSerializable来更改此行为。)JSON更可移植
,目前可能还有其他一些我想不到的区别。
比较两者的简单速度测试
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
// Make a big, honkin test array
// You may need to adjust this depth to avoid memory limit errors
$testArray = fillArray(0, 5);
// Time json encoding
$start = microtime(true);
json_encode($testArray);
$jsonTime = microtime(true) - $start;
echo "JSON encoded in $jsonTime seconds\n";
// Time serialization
$start = microtime(true);
serialize($testArray);
$serializeTime = microtime(true) - $start;
echo "PHP serialized in $serializeTime seconds\n";
// Compare them
if ($jsonTime < $serializeTime) {
printf("json_encode() was roughly %01.2f%% faster than serialize()\n", ($serializeTime / $jsonTime - 1) * 100);
}
else if ($serializeTime < $jsonTime ) {
printf("serialize() was roughly %01.2f%% faster than json_encode()\n", ($jsonTime / $serializeTime - 1) * 100);
} else {
echo "Impossible!\n";
}
function fillArray( $depth, $max ) {
static $seed;
if (is_null($seed)) {
$seed = array('a', 2, 'c', 4, 'e', 6, 'g', 8, 'i', 10);
}
if ($depth < $max) {
$node = array();
foreach ($seed as $key) {
$node[$key] = fillArray($depth + 1, $max);
}
return $node;
}
return 'empty';
}
#2 楼
JSON比PHP的序列化格式更简单,更快捷,因此应使用JSON,除非:您要存储深度嵌套的数组:
json_decode()
:“如果JSON,此函数将返回false编码数据的深度超过127个元素。“ 您正在存储需要反序列化为正确类的对象
您正在与不支持json_decode
的旧PHP版本进行交互br />
评论
好答案。哈哈,深达127级似乎有点疯狂;值得庆幸的是,我最多只能参加2-3次比赛。您是否有任何数据可以支持json_decode / json_encode比反序列化/序列化更快的事实?
–凯尔·法里斯(KyleFarris)
09年4月29日在20:34
我确实做了一段时间的测试,并且json更快地发布了-尽管我再也没有数据了。
–格雷格
09年4月29日在21:02
“ 5.3.0添加了可选深度。默认的递归深度从128增加到512”
–giorgio79
2011-12-15 6:30
我还要在上面的列表中添加一个项目:如果您的数据可能包含无效的UTF-8字节序列,则不应使用json_encode()。对于此类数据,它仅返回false。例如尝试:var_dump(json_encode(“ \ xEF \ xEF”));
–pako
15年5月20日在20:28
总的来说,它更快是不正确的。如果您有一个约500个条目的小型数组,那么反序列化/序列化实际上比json_decode / json_encode(PHP 5.6.19)快200-400%。
–亚当
16年8月12日在6:51
#3 楼
我写了一篇有关此主题的博客文章:“是否缓存一个大数组:JSON,序列化还是var_export?”。在这篇文章中,显示了序列化是小型到大型阵列的最佳选择。对于非常大的数组(> 70MB),JSON是更好的选择。评论
该链接不再可用。
–马丁·托马
15年2月28日在5:35
谢谢,驼鹿,我已经更新了链接。尽管该文章已有6年历史了,对于当前的PHP版本而言可能不够准确。
–塔可
15年3月2日在10:04
我做了一些测试,并做了一个简单的函数来测试它,使用大数组(使用了Peter Bailey的函数),json_encode()的速度比serialize()快80%至150%(实际上在上下)。 ,约有300次迭代。但是,当使用较小的数组(array(“ teams” => array(1 => array(4个玩家数组),2 => array(4个玩家数组))))时,我确实进行了750,000次迭代测试并序列化了在这种情况下,速度大约要快6%到10%。我的函数取所有迭代的平均时间并进行比较。我可能会在这里张贴它作为答案之一
– MiChAeLoKGB
15年5月23日在23:36
如果数据仅由PHP使用,则var_export是我的事情。只需要小心包含思想中可能出现的语法错误。
– Gfra54
2015年10月15日在10:14
博客不再存在
– popeye
18-10-3在11:50
#4 楼
您可能也对https://github.com/phadej/igbinary感兴趣-它为PHP提供了不同的序列化“引擎”。我的随机/任意“性能”数据是使用PHP 5.3。 5在64位平台上显示:
JSON编码为2.180496931076秒
JSON解码为9.8368630409241秒
序列化的“ String “ size:13993
本地PHP:
PHP在2.9125759601593秒内序列化了
PHP在6.4348418712616秒内未序列化了
序列化了“字符串”的大小:20769
二进制:
WIN igbinary在1.6099879741669秒内序列化
WIN igbinrary在4.7737920284271秒内未序列化
/>
WIN序列化的“字符串”大小:4467
因此,使用igbinary_serialize()和igbinary_unserialize()更快,并且使用更少的磁盘空间。
我使用了上面的fillArray(0,3)代码,但是使数组键成为更长的字符串。
igbinary可以存储sa数据类型可以像PHP的本机序列化一样(因此对象等没有问题),如果愿意,可以告诉PHP5.3将其用于会话处理。
另请参见http:// ilia。 ws / files / zendcon_2010_hidden_features.pdf-特别是幻灯片14/15/16
#5 楼
Y刚刚测试了序列化和json编码和解码,加上将存储字符串的大小。JSON encoded in 0.067085981369 seconds. Size (1277772)
PHP serialized in 0.12110209465 seconds. Size (1955548)
JSON decode in 0.22470498085 seconds
PHP serialized in 0.211947917938 seconds
json_encode() was roughly 80.52% faster than serialize()
unserialize() was roughly 6.02% faster than json_decode()
JSON string was roughly 53.04% smaller than Serialized string
我们可以得出结论,JSON编码速度更快,并且生成的字符串更小,但是反序列化可以更快地解码字符串。
评论
我不知道为什么人们总是对这么小的数据集进行性能测试。这样一来,您将承担所有增加结果错误的开销。如果人们对性能感兴趣,那可能是因为他们拥有非常庞大的数据集,因为一次获取微秒是没有意义的。
–扬·斯贡(Yann Sagon)
2012年5月14日14:04
我经常会遍历许多小型数据集。拥有数百个小型数据集,每个数据集获得1mS仍然很有趣。
– Teson
2014年4月11日在8:46
@YannSagon即使使用小的数据集,进行性能测试也是有意义的。在测试之前您应该如何知道是否只有大约1微秒?
–亚当
16年8月12日在6:57
那我一定做错了吗?因为我只是进行基准测试,所以序列化和反序列化速度更快,字符串更小
–user11995521
7月24日19:59
#6 楼
如果要缓存的信息最终将在以后的某个时间点“包含”,则可能需要尝试使用var_export。这样,您只能在“序列化”中获得成功,而不会在“序列化”中获得成功。评论
这很可能是最快的方法。我在SO上写了一个示例“ PHP-快速序列化/反序列化”:stackoverflow.com/questions/2545455 / ...
–dave1010
10年7月30日在8:56
#7 楼
我扩大了测试范围,以包含反序列化性能。这是我得到的数字。Serialize
JSON encoded in 2.5738489627838 seconds
PHP serialized in 5.2861361503601 seconds
Serialize: json_encode() was roughly 105.38% faster than serialize()
Unserialize
JSON decode in 10.915472984314 seconds
PHP unserialized in 7.6223039627075 seconds
Unserialize: unserialize() was roughly 43.20% faster than json_decode()
所以json似乎编码速度更快,但解码速度却很慢。因此,这可能取决于您的应用程序和您最希望做的事情。
#8 楼
真是一个不错的话题,在阅读了一些答案之后,我想分享关于该主题的实验。我有一个用例,几乎每次我与数据库对话时都需要查询一些“巨大”表(不要不要问为什么,只是一个事实)。数据库缓存系统不合适,因为它不会缓存不同的请求,所以我虽然是关于php缓存系统。
我尝试了
apcu
,但它不能满足需求,内存在此方面不够可靠案件。下一步是通过序列化缓存到文件中。表有14355个条目,其中有18列,这些是我对读取序列化缓存的测试和统计信息:
json_encode
/ json_decode
的主要不便之处在于将所有内容转换为StdClass
实例(或对象)。如果需要循环,将其转换为数组可能是您要做的,是的,它增加了转换时间。平均时间:780.2 ms;内存使用:41.5MB;缓存文件大小:3.8MB
Msgpack
@hutch提到了msgpack。漂亮的网站。我们可以尝试一下吗?
平均时间:497毫秒;内存使用:32MB;缓存文件大小:2.8MB
更好,但是需要新的扩展名;编译有时害怕的人...
IgBinary
@GingerDog提到igbinary。请注意,我设置
igbinary.compact_strings=Off
的原因是,我更关心读取性能,而不是文件大小。平均时间:411.4毫秒;内存使用:36.75MB;缓存文件大小:3.3MB
比msg包更好。
serialize
/ unserialize
平均时间:477.2 ms;内存使用:36.25MB;缓存文件大小:5.9MB
性能比JSON更好,数组越大,
json_decode
越慢,但是您已经是一个新手了。这些外部扩展名缩小了文件的大小,在纸面上看起来不错。数字不会说谎*。如果您获得与标准PHP函数几乎相同的结果,那么编译扩展的意义何在?
我们还可以根据您的需求推断出您会选择与其他人不同的东西:
IgBinary非常好,并且性能优于MsgPack
Msgpack在压缩数据方面更好(请注意,我没有尝试过igbinary
compact.string选项)。
不想编译?使用标准。
就是这样,另一种序列化方法比较可以帮助您选择一种!
*已在PHPUnit 3.7.31和php 5.5.10中进行了测试-仅使用标准hardrive和旧版本进行解码双核CPU-10个相同用例测试的平均值,您的统计信息可能有所不同
评论
为什么不将标志传递给json_decode强制返回数组?
– Alex Yaroshevich
2014年11月23日在23:51
因为它很慢。我没有对此进行测试,但我认为简单地从php强制更改类型会更快。
–soyuka
2014年11月24日20:59
我只知道创建数组要比PHP中的对象快得多。
– Alex Yaroshevich
2014年11月25日下午6:44
因此,您正在谈论json_decode($ object,true),基本上它的作用与(array)json_decode($ object)相同,但是递归地实现,因此行为相同,并且在两种情况下都将产生巨大的成本。请注意,我尚未测试StdClass和数组之间的性能差异,但这并不是重点。
–soyuka
2014年11月25日10:37
我确定这是另一笔费用,因为它是在没有对象的较低级别完成的。
– Alex Yaroshevich
2014年11月26日15:00
#9 楼
好像是序列化是我要使用的序列,原因有两个:有人指出,反序列化比json_decode更快,而且“读”的情况听起来比“写”的可能性更大'case。
当字符串中包含无效的UTF-8字符时,我遇到了json_encode的问题。发生这种情况时,该字符串最终为空,从而导致信息丢失。
#10 楼
我已经在包含各种数据(字符串,NULL,整数)的相当复杂,轻度嵌套的多哈希中进行了非常彻底的测试,并且序列化/反序列化的结果比json_encode / json_decode快得多。json在我的测试中唯一的优势是它的“打包”大小较小。
这些都是在PHP 5.3.3下完成的,如果您需要更多详细信息,请通知我。
这里是测试结果,然后是产生它们的代码。我无法提供测试数据,因为它会显示我不能随意散发出来的信息。
JSON encoded in 2.23700618744 seconds
PHP serialized in 1.3434419632 seconds
JSON decoded in 4.0405561924 seconds
PHP unserialized in 1.39393305779 seconds
serialized size : 14549
json_encode size : 11520
serialize() was roughly 66.51% faster than json_encode()
unserialize() was roughly 189.87% faster than json_decode()
json_encode() string was roughly 26.29% smaller than serialize()
// Time json encoding
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
json_encode( $test );
}
$jsonTime = microtime( true ) - $start;
echo "JSON encoded in $jsonTime seconds<br>";
// Time serialization
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
serialize( $test );
}
$serializeTime = microtime( true ) - $start;
echo "PHP serialized in $serializeTime seconds<br>";
// Time json decoding
$test2 = json_encode( $test );
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
json_decode( $test2 );
}
$jsonDecodeTime = microtime( true ) - $start;
echo "JSON decoded in $jsonDecodeTime seconds<br>";
// Time deserialization
$test2 = serialize( $test );
$start = microtime( true );
for($i = 0; $i < 10000; $i++) {
unserialize( $test2 );
}
$unserializeTime = microtime( true ) - $start;
echo "PHP unserialized in $unserializeTime seconds<br>";
$jsonSize = strlen(json_encode( $test ));
$phpSize = strlen(serialize( $test ));
echo "<p>serialized size : " . strlen(serialize( $test )) . "<br>";
echo "json_encode size : " . strlen(json_encode( $test )) . "<br></p>";
// Compare them
if ( $jsonTime < $serializeTime )
{
echo "json_encode() was roughly " . number_format( ($serializeTime / $jsonTime - 1 ) * 100, 2 ) . "% faster than serialize()";
}
else if ( $serializeTime < $jsonTime )
{
echo "serialize() was roughly " . number_format( ($jsonTime / $serializeTime - 1 ) * 100, 2 ) . "% faster than json_encode()";
} else {
echo 'Unpossible!';
}
echo '<BR>';
// Compare them
if ( $jsonDecodeTime < $unserializeTime )
{
echo "json_decode() was roughly " . number_format( ($unserializeTime / $jsonDecodeTime - 1 ) * 100, 2 ) . "% faster than unserialize()";
}
else if ( $unserializeTime < $jsonDecodeTime )
{
echo "unserialize() was roughly " . number_format( ($jsonDecodeTime / $unserializeTime - 1 ) * 100, 2 ) . "% faster than json_decode()";
} else {
echo 'Unpossible!';
}
echo '<BR>';
// Compare them
if ( $jsonSize < $phpSize )
{
echo "json_encode() string was roughly " . number_format( ($phpSize / $jsonSize - 1 ) * 100, 2 ) . "% smaller than serialize()";
}
else if ( $phpSize < $jsonSize )
{
echo "serialize() string was roughly " . number_format( ($jsonSize / $phpSize - 1 ) * 100, 2 ) . "% smaller than json_encode()";
} else {
echo 'Unpossible!';
}
评论
我刚刚用PHP 5.4.12执行了类似的测试,并发现了类似的结果:{un,} serialize更快。我的数据是嵌套3级深度的哈希(序列化900k)。
–sorpigal
13年12月18日在20:39
#11 楼
我也做了一个小基准。我的结果是一样的。但是我需要解码性能。我注意到的地方,就像上面的几个人所说的那样,unserialize
比json_decode
快。 unserialize
大约花费json_decode
时间的60-70%。因此结论很简单:当需要编码时,请使用
json_encode
;当解码时需要性能时,请使用unserialize
。因为不能合并这两个函数,所以必须在需要更高性能的地方选择。我在伪代码中的基准测试:
用$ arr定义数组x <100的一些随机键和值
; x ++;序列化并json_encode一个$ arr
的array_rand为y <1000; y ++; json_decode json编码的字符串-y的计算时间
<1000; y ++;将序列化的字符串反序列化-calc time
返回更快的结果
平均而言:unserialize在json_decode的4倍上赢得了96次。平均间隔1.5毫秒超过2.5毫秒。
#12 楼
在做出最终决定之前,请注意JSON格式对于关联数组并不安全-json_decode()
会将其返回为对象,而不是:$config = array(
'Frodo' => 'hobbit',
'Gimli' => 'dwarf',
'Gandalf' => 'wizard',
);
print_r($config);
print_r(json_decode(json_encode($config)));
输出为:
Array
(
[Frodo] => hobbit
[Gimli] => dwarf
[Gandalf] => wizard
)
stdClass Object
(
[Frodo] => hobbit
[Gimli] => dwarf
[Gandalf] => wizard
)
评论
确实,你是对的。我的意思是毕竟是Javascript对象符号!幸运的是,如果您知道使用json_encode编码的是一个关联数组,则可以轻松地将其强制返回一个数组,如下所示:$ json = json_encode($ some_assoc_array); $ back_to_array =(array)json_decode($ json);还要注意的是,您可以用与PHP中的数组相同的方式访问对象,因此在典型情况下,甚至都不知道有什么区别。好点!
–凯尔·法里斯(KyleFarris)
09年12月7日在21:10
@toomuchphp,对不起,但您错了。 json_decode的第二个参数'bool $ assoc = false'使json_decode产生一个数组。 @KyleFarris,这也应该比使用类型转换数组更快。
– janpio
2010-1-20 14:30
答案不正确。当使用true作为函数的第二个参数时,json_decode()将返回关联数组而不是对象。
– Marvin Saldinger
15年7月7日在7:06
#13 楼
首先,我更改了脚本以进行更多基准测试(也可以运行1000次而不是仅运行1次):<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
// Make a big, honkin test array
// You may need to adjust this depth to avoid memory limit errors
$testArray = fillArray(0, 5);
$totalJsonTime = 0;
$totalSerializeTime = 0;
$totalJsonWins = 0;
for ($i = 0; $i < 1000; $i++) {
// Time json encoding
$start = microtime(true);
$json = json_encode($testArray);
$jsonTime = microtime(true) - $start;
$totalJsonTime += $jsonTime;
// Time serialization
$start = microtime(true);
$serial = serialize($testArray);
$serializeTime = microtime(true) - $start;
$totalSerializeTime += $serializeTime;
if ($jsonTime < $serializeTime) {
$totalJsonWins++;
}
}
$totalSerializeWins = 1000 - $totalJsonWins;
// Compare them
if ($totalJsonTime < $totalSerializeTime) {
printf("json_encode() (wins: $totalJsonWins) was roughly %01.2f%% faster than serialize()\n", ($totalSerializeTime / $totalJsonTime - 1) * 100);
} else {
printf("serialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than json_encode()\n", ($totalJsonTime / $totalSerializeTime - 1) * 100);
}
$totalJsonTime = 0;
$totalJson2Time = 0;
$totalSerializeTime = 0;
$totalJsonWins = 0;
for ($i = 0; $i < 1000; $i++) {
// Time json decoding
$start = microtime(true);
$orig = json_decode($json, true);
$jsonTime = microtime(true) - $start;
$totalJsonTime += $jsonTime;
$start = microtime(true);
$origObj = json_decode($json);
$jsonTime2 = microtime(true) - $start;
$totalJson2Time += $jsonTime2;
// Time serialization
$start = microtime(true);
$unserial = unserialize($serial);
$serializeTime = microtime(true) - $start;
$totalSerializeTime += $serializeTime;
if ($jsonTime < $serializeTime) {
$totalJsonWins++;
}
}
$totalSerializeWins = 1000 - $totalJsonWins;
// Compare them
if ($totalJsonTime < $totalSerializeTime) {
printf("json_decode() was roughly %01.2f%% faster than unserialize()\n", ($totalSerializeTime / $totalJsonTime - 1) * 100);
} else {
printf("unserialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than json_decode()\n", ($totalJsonTime / $totalSerializeTime - 1) * 100);
}
// Compare them
if ($totalJson2Time < $totalSerializeTime) {
printf("json_decode() was roughly %01.2f%% faster than unserialize()\n", ($totalSerializeTime / $totalJson2Time - 1) * 100);
} else {
printf("unserialize() (wins: $totalSerializeWins) was roughly %01.2f%% faster than array json_decode()\n", ($totalJson2Time / $totalSerializeTime - 1) * 100);
}
function fillArray( $depth, $max ) {
static $seed;
if (is_null($seed)) {
$seed = array('a', 2, 'c', 4, 'e', 6, 'g', 8, 'i', 10);
}
if ($depth < $max) {
$node = array();
foreach ($seed as $key) {
$node[$key] = fillArray($depth + 1, $max);
}
return $node;
}
return 'empty';
}
我使用了PHP 7: />
PHP 7.0.14(cli)(内置:2017年1月18日19:13:23)(NTS)版权所有(c)
1997-2016 PHP Group Zend Engine v3。 0.0,版权所有(c)1998-2016
Zend Technologies
与Zend OPcache v7.0.14,版权所有(c)1999-2016,由Zend Technologies
我的结果是:
serialize()(获胜:999)比json_encode()快约10.98%
unserialize()(获胜:987)快约33.26%比json_decode()
unserialize()(获胜:987)比数组快约48.35%
json_decode()
所以很明显,序列化/反序列化是最快的方法,而json_encode / decode是最可移植的。
如果您考虑的情况下,读取/写入序列化数据的次数是非PHP系统发送或接收的10倍或更多倍,最好还是使用序列化/反序列化,并在序列化之前先将其设为json_encode或json_decode。
#14 楼
在此处查看结果(对不起,将PHP代码放入JS代码框中的黑客的攻击):http://jsfiddle.net/newms87/h3b0a0ha/embedded/result/
<结果:
serialize()
和unserialize()
在PHP 5.4中的不同大小数组上都显着更快。我对真实数据进行了测试,以比较json_encode与序列化以及json_decode与反序列化。该测试在生产中的电子商务站点的缓存系统上运行。它只是获取缓存中已经存在的数据,并测试编码/解码(或序列化/反序列化)所有数据的时间,然后将其放在一个易于查看的表格中。
PHP 5.4共享托管服务器。
结果非常确定,对于这些大小数据集,序列化和反序列化无疑是赢家。特别是对于我的用例而言,json_decode和unserialize对于缓存系统而言是最重要的。 Unserialize在这里几乎是无处不在的赢家。它通常是json_decode的2到4倍(有时是6或7倍)。
有趣的是,注意到@ peter-bailey的结果有所不同。
这是用于生成结果的PHP代码:
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
function _count_depth($array)
{
$count = 0;
$max_depth = 0;
foreach ($array as $a) {
if (is_array($a)) {
list($cnt, $depth) = _count_depth($a);
$count += $cnt;
$max_depth = max($max_depth, $depth);
} else {
$count++;
}
}
return array(
$count,
$max_depth + 1,
);
}
function run_test($file)
{
$memory = memory_get_usage();
$test_array = unserialize(file_get_contents($file));
$memory = round((memory_get_usage() - $memory) / 1024, 2);
if (empty($test_array) || !is_array($test_array)) {
return;
}
list($count, $depth) = _count_depth($test_array);
//JSON encode test
$start = microtime(true);
$json_encoded = json_encode($test_array);
$json_encode_time = microtime(true) - $start;
//JSON decode test
$start = microtime(true);
json_decode($json_encoded);
$json_decode_time = microtime(true) - $start;
//serialize test
$start = microtime(true);
$serialized = serialize($test_array);
$serialize_time = microtime(true) - $start;
//unserialize test
$start = microtime(true);
unserialize($serialized);
$unserialize_time = microtime(true) - $start;
return array(
'Name' => basename($file),
'json_encode() Time (s)' => $json_encode_time,
'json_decode() Time (s)' => $json_decode_time,
'serialize() Time (s)' => $serialize_time,
'unserialize() Time (s)' => $unserialize_time,
'Elements' => $count,
'Memory (KB)' => $memory,
'Max Depth' => $depth,
'json_encode() Win' => ($json_encode_time > 0 && $json_encode_time < $serialize_time) ? number_format(($serialize_time / $json_encode_time - 1) * 100, 2) : '',
'serialize() Win' => ($serialize_time > 0 && $serialize_time < $json_encode_time) ? number_format(($json_encode_time / $serialize_time - 1) * 100, 2) : '',
'json_decode() Win' => ($json_decode_time > 0 && $json_decode_time < $serialize_time) ? number_format(($serialize_time / $json_decode_time - 1) * 100, 2) : '',
'unserialize() Win' => ($unserialize_time > 0 && $unserialize_time < $json_decode_time) ? number_format(($json_decode_time / $unserialize_time - 1) * 100, 2) : '',
);
}
$files = glob(dirname(__FILE__) . '/system/cache/*');
$data = array();
foreach ($files as $file) {
if (is_file($file)) {
$result = run_test($file);
if ($result) {
$data[] = $result;
}
}
}
uasort($data, function ($a, $b) {
return $a['Memory (KB)'] < $b['Memory (KB)'];
});
$fields = array_keys($data[0]);
?>
<table>
<thead>
<tr>
<?php foreach ($fields as $f) { ?>
<td style="text-align: center; border:1px solid black;padding: 4px 8px;font-weight:bold;font-size:1.1em"><?= $f; ?></td>
<?php } ?>
</tr>
</thead>
<tbody>
<?php foreach ($data as $d) { ?>
<tr>
<?php foreach ($d as $key => $value) { ?>
<?php $is_win = strpos($key, 'Win'); ?>
<?php $color = ($is_win && $value) ? 'color: green;font-weight:bold;' : ''; ?>
<td style="text-align: center; vertical-align: middle; padding: 3px 6px; border: 1px solid gray; <?= $color; ?>"><?= $value . (($is_win && $value) ? '%' : ''); ?></td>
<?php } ?>
</tr>
<?php } ?>
</tbody>
</table>
#15 楼
只是一个麻烦-如果您想将数据序列化为易于读取和理解的内容(例如JSON),但具有更高的压缩率和更高的性能,则应该签出messagepack。评论
如果只是fyi,最好将其作为注释。
–铁皮科
16-2-29在3:29
#16 楼
我知道这很晚了,但是答案已经很老了,我认为我的基准测试可能会有所帮助,因为我刚刚在PHP 7.4中进行了测试Serialize / Unserialize比JSON快得多,占用的内存和空间更少,并且在PHP中独占win头7.4,但我不确定我的测试是最有效还是最好,
我基本上已经创建了一个PHP文件,该文件返回了一个数组,该数组是我编码,序列化,然后解码和未序列化的。
$array = include __DIR__.'/../tests/data/dao/testfiles/testArray.php';
//JSON ENCODE
$json_encode_memory_start = memory_get_usage();
$json_encode_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$encoded = json_encode($array);
}
$json_encode_time_end = microtime(true);
$json_encode_memory_end = memory_get_usage();
$json_encode_time = $json_encode_time_end - $json_encode_time_start;
$json_encode_memory =
$json_encode_memory_end - $json_encode_memory_start;
//SERIALIZE
$serialize_memory_start = memory_get_usage();
$serialize_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$serialized = serialize($array);
}
$serialize_time_end = microtime(true);
$serialize_memory_end = memory_get_usage();
$serialize_time = $serialize_time_end - $serialize_time_start;
$serialize_memory = $serialize_memory_end - $serialize_memory_start;
//Write to file time:
$fpc_memory_start = memory_get_usage();
$fpc_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$fpc_bytes =
file_put_contents(
__DIR__.'/../tests/data/dao/testOneBigFile',
'<?php return '.var_export($array,true).' ?>;'
);
}
$fpc_time_end = microtime(true);
$fpc_memory_end = memory_get_usage();
$fpc_time = $fpc_time_end - $fpc_time_start;
$fpc_memory = $fpc_memory_end - $fpc_memory_start;
//JSON DECODE
$json_decode_memory_start = memory_get_usage();
$json_decode_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$decoded = json_encode($encoded);
}
$json_decode_time_end = microtime(true);
$json_decode_memory_end = memory_get_usage();
$json_decode_time = $json_decode_time_end - $json_decode_time_start;
$json_decode_memory =
$json_decode_memory_end - $json_decode_memory_start;
//UNSERIALIZE
$unserialize_memory_start = memory_get_usage();
$unserialize_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$unserialized = unserialize($serialized);
}
$unserialize_time_end = microtime(true);
$unserialize_memory_end = memory_get_usage();
$unserialize_time = $unserialize_time_end - $unserialize_time_start;
$unserialize_memory =
$unserialize_memory_end - $unserialize_memory_start;
//GET FROM VAR EXPORT:
$var_export_memory_start = memory_get_usage();
$var_export_time_start = microtime(true);
for ($i=0; $i < 20000; $i++) {
$array = include __DIR__.'/../tests/data/dao/testOneBigFile';
}
$var_export_time_end = microtime(true);
$var_export_memory_end = memory_get_usage();
$var_export_time = $var_export_time_end - $var_export_time_start;
$var_export_memory = $var_export_memory_end - $var_export_memory_start;
结果:
Var导出长度:11447
序列化长度:11541
Json编码长度:11895
文件放入内容字节:11464
Json编码时间:1.9197590351105
序列化时间:0.160325050354
FPC时间:6.2793469429016
Json编码内存:12288
序列化内存:12288
FPC内存:0
JSON解码时间:1.7493588924408
反序列化时间:0.19309520721436
Var导出并包括:3.1974139213562
JSON解码后的内存:16384
反序列化内存:14360
Var导出并包括:192
#17 楼
如果您想备份数据并将其还原到另一台计算机上或通过FTP还原,JSON会更好。例如序列化(如果您将数据存储在Windows服务器上),通过FTP下载并还原到Windows在Linux上,由于charachter重新编码,它无法再工作了,因为序列化存储了字符串的长度,并且在Unicode> UTF-8转码中,某些1字节charachter可能变成2字节长,导致算法崩溃。 >
#18 楼
THX-对于此基准代码:我在阵列上用于配置的结果有以下不足:
JSON编码为0.0031511783599854秒
PHP序列化为0.0037961006164551秒
json_encode()
大约为20.47%比serialize()
快以0.0070841312408447秒编码的JSON
在0.0035839080810547秒中序列化的PHP
unserialize()
比json_encode()
快约97.66%所以-对您自己的数据进行测试。
评论
您的意思是“ unserialize()中的json_decode()比json_encode()快约97.66%,是吗?
– Meezaan-ud-Din
2014年9月1日14:22
#19 楼
如果要总结一下人们在这里所说的话,json_decode / encode似乎比序列化/反序列化BUT更快。如果执行var_dump,则序列化对象的类型将被更改。
如果出于某种原因要保留类型,请进行序列化!
(例如,尝试stdClass vs array)
序列化/反序列化:
Array cache:
array (size=2)
'a' => string '1' (length=1)
'b' => int 2
Object cache:
object(stdClass)[8]
public 'field1' => int 123
This cache:
object(Controller\Test)[8]
protected 'view' =>
json编码/解码
Array cache:
object(stdClass)[7]
public 'a' => string '1' (length=1)
public 'b' => int 2
Object cache:
object(stdClass)[8]
public 'field1' => int 123
This cache:
object(stdClass)[8]
如您所见,json_encode / decode将所有内容转换为stdClass,效果不好,对象信息丢失了...因此决定需要,特别是如果不仅是数组...
评论
请注意:大多数其他答案都说序列化/反序列化速度更快。
– Ecker00
18年4月14日在21:30
#20 楼
我建议您使用超级缓存,这是一种不会使用json_encode
或serialize
的文件缓存机制。与其他PHP Cache机制相比,它使用简单,而且速度非常快。 https://packagist.org/packages/smart-php/super-cache
例如:
<?php
require __DIR__.'/vendor/autoload.php';
use SuperCache\SuperCache as sCache;
//Saving cache value with a key
// sCache::cache('<key>')->set('<value>');
sCache::cache('myKey')->set('Key_value');
//Retrieving cache value with a key
echo sCache::cache('myKey')->get();
?>
评论
-1。尽管这可能是一个更好的解决方案,但此答案中没有任何内容实际上可以回答OP的问题。将来,也许可以尝试回答这个问题,但在底部却提出了一个替代解决方案可能值得研究的建议。
– starbeamrainbowlabs
19年8月15日在22:50
评论
“ JSON将UTF-8字符转换为Unicode转义序列。”不再必须是真的:我们现在有了JSON_UNESCAPED_UNICODE。
– TRiG
2012年11月24日17:01
在这里将近5年之后,我再次运行了测试(只是json_encode),平均速度比现在序列化快131%。因此,相对于5.3.x,5.4.x中必须对该功能进行一些相当不错的改进。具体来说,我在CentOS 6上运行5.4.24。所以,对JSON来说是这样!
–凯尔·法里斯(KyleFarris)
2014年3月7日在21:56
在我的情况下,我们只编码一次并进行大量解码,因此我们对json_decode和unserialize进行了基准测试,结果是在0.06662392616272秒内对JSON进行了dcode编码。
PHP在0.093269109725952秒内未序列化了PHP
json_decode()比unserialize()快了39.99%
–user1642018
2014年7月28日在3:05
有趣的是:如果在3v4l.org上运行此代码,则最新的PHP7开发版本的序列化运行速度比json_encode快:“ serialize()的速度比json_encode()快76.53%”
– marcvangend
15年3月9日在12:46
2017年,PHP 7.1和serialize()比json_encode()快35.04%
– Elias Soares
17-10-25在17:01