我需要将多维关联数据数组存储在平面文件中以进行缓存。我可能偶尔会遇到需要将其转换为 JSON 以在我的 Web 应用程序中使用,但绝大多数时间我将直接在 PHP 中使用该数组。
在这个文本文件中将数组存储为 JSON 或 PHP 序列化数组会更有效吗?我环顾四周,似乎在最新版本的 PHP (5.3) 中,json_decode
实际上比 unserialize
快。
我目前倾向于将数组存储为 JSON,因为我觉得如果必要的话它更容易被人类阅读,它可以在 PHP 和 JavaScript 中使用,而且几乎不需要付出任何努力,而且根据我的阅读,它甚至可能是解码速度更快(但不确定编码)。
有谁知道任何陷阱?任何人都有很好的基准来展示这两种方法的性能优势吗?
$array = array('foo' => 'bar'); file_put_contents('foo.php', "<?php return ".var_export($array, true) . ";");
。和 。 $array = file_get_contents('foo.php')));
当然,如果这是针对更大的数据量,我可能会选择.... CSV。所以也许不是最性感的——但出于某种原因,它的存在时间比我们都长——而且 PHP 对非常大的数据集的部分或流式访问提供了出色的支持。
取决于你的优先级。
如果性能是您的绝对驾驶特性,那么一定要使用最快的。在做出选择之前,请确保您对差异有充分的了解
与 serialize() 不同,您需要添加额外的参数以保持 UTF-8 字符不变: json_encode($array, JSON_UNESCAPED_UNICODE) (否则它将 UTF-8 字符转换为 Unicode 转义序列)。
JSON 将不记得对象的原始类是什么(它们总是作为 stdClass 的实例恢复)。
您不能将 __sleep() 和 __wakeup() 与 JSON 结合使用
默认情况下,只有公共属性使用 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';
}
JSON 比 PHP 的序列化格式更简单、更快速,除非:
您正在存储深度嵌套的数组:json_decode():“如果 JSON 编码的数据深度超过 127 个元素,此函数将返回 false。”
您将需要反序列化的对象存储为正确的类
您正在与不支持 json_decode 的旧 PHP 版本进行交互
我写了一篇关于这个主题的博文:“Cache a large array: JSON, serialize or var_export?”。在这篇文章中,表明序列化是小型到大型数组的最佳选择。对于非常大的数组(> 70MB),JSON 是更好的选择。
json_encode()
的速度大约提高了 80% 到 150%(它确实在上升那里)比 serialize()
,大约 300 次迭代。但是在使用较小的数组 (array("teams" => array(1 => array(4 arrays of players), 2 => array(4 arrays of players)))
) 时,我确实使用了 750,000 次迭代进行了测试,在这种情况下,serialize()
的速度大约提高了 6% 到 10%。我的函数取所有迭代的平均时间并进行比较。我可能会把它贴在这里作为答案之一
您可能还对 https://github.com/phadej/igbinary 感兴趣 - 它为 PHP 提供了不同的序列化“引擎”。
我的随机/任意“性能”数据,在 64 位平台上使用 PHP 5.3.5 显示:
JSON:
JSON 在 2.180496931076 秒内编码
JSON 在 9.8368630409241 秒内解码
序列化的“字符串”大小: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 可以存储与 PHP 的本机序列化相同的数据类型(因此对象等没有问题),如果您愿意,可以告诉 PHP5.3 将其用于会话处理。
另请参阅 http://ilia.ws/files/zendcon_2010_hidden_features.pdf - 特别是 2016 年 14 月 15 日的幻灯片
刚刚测试了序列化和 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 编码更快并产生更小的字符串,但反序列化更快地解码字符串。
如果您正在缓存您最终想要在以后“包含”的信息,您可能需要尝试使用 var_export。这样,您只会在“序列化”中受到打击,而不是在“反序列化”中受到打击。
我增加了测试以包括反序列化性能。这是我得到的数字。
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 似乎编码速度更快,但解码速度慢。因此,这可能取决于您的应用程序以及您最期望做的事情。
非常好的话题,在阅读了几个答案之后,我想分享我在这个主题上的实验。
我有一个用例,几乎每次我与数据库交谈时都需要查询一些“巨大”的表(不要问为什么,只是一个事实)。数据库缓存系统不合适,因为它不会缓存不同的请求,所以我想到了 php 缓存系统。
我试过 apcu
但它不符合需要,在这种情况下内存不够可靠。下一步是通过序列化缓存到文件中。
表有 18 列的 14355 个条目,这些是我在读取序列化缓存时的测试和统计信息:
JSON:
正如大家所说,json_encode
/json_decode
的主要不便之处在于它将所有内容都转换为 StdClass
实例(或对象)。如果你需要循环它,将它转换为一个数组是你可能会做的,是的,它增加了转换时间
平均时间:780.2 毫秒;内存使用:41.5MB;缓存文件大小:3.8MB
消息包
@hutch 提到了 msgpack。漂亮的网站。让我们试一试好吗?
平均时间:497 毫秒;内存使用:32MB;缓存文件大小:2.8MB
这更好,但需要新的扩展;编译有时害怕的人...
二进制
@GingerDog 提到 igbinary。请注意,我之所以设置 igbinary.compact_strings=Off
,是因为我更关心阅读性能而不是文件大小。
平均时间:411.4 毫秒;内存使用:36.75MB;缓存文件大小:3.3MB
比味精包好。不过,这个也需要编译。
序列化/反序列化
平均时间:477.2 毫秒;内存使用:36.25MB;缓存文件大小:5.9MB
比 JSON 更好的性能,数组越大,json_decode
越慢,但你已经是新的了。
这些外部扩展正在缩小文件大小,并且在纸上看起来很棒。数字不会说谎*。如果您获得与使用标准 PHP 函数几乎相同的结果,那么编译扩展的意义何在?
我们还可以推断,根据您的需求,您会选择与其他人不同的东西:
IgBinary 真的很好,性能比 MsgPack 好
Msgpack 更擅长压缩数据(请注意,我没有尝试过 igbinary compact.string 选项)。
不想编译?使用标准。
就是这样,另一种序列化方法比较来帮助您选择一个!
*使用 PHPUnit 3.7.31、php 5.5.10 测试 - 仅使用标准硬盘和旧双核 CPU 解码 - 10 次相同用例测试的平均数,您的统计数据可能不同
json_decode($object, true)
,基本上它会和 (array) json_decode($object)
做同样的事情,但会递归,所以这将是相同的行为,并且在这两种情况下都会产生很大的成本。请注意,我没有测试 StdClass
和 array
之间的性能差异,但这并不是重点。
似乎序列化是我要使用的一个,原因有两个:
有人指出,反序列化比 json_decode 更快,“读”的情况听起来比“写”的情况更有可能。
当字符串包含无效的 UTF-8 字符时,我遇到了 json_encode 问题。发生这种情况时,字符串最终为空,导致信息丢失。
我已经在一个相当复杂的、温和嵌套的多重哈希上对此进行了非常彻底的测试,其中包含各种数据(字符串、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!';
}
我也做了一个小基准测试。我的结果是一样的。但我需要解码性能。在我注意到的地方,就像上面的一些人所说的那样,unserialize
比 json_decode
快。 unserialize
大约需要 json_decode
时间的 60-70%。所以结论很简单:当你需要编码性能时,使用json_encode
,当你需要解码性能时,使用unserialize
。因为您不能合并这两个功能,所以您必须在需要更高性能的地方做出选择。
我的伪基准:
使用一些随机键和值定义数组 $arr
对于 x < 100; x++;序列化和 json_encode $arr 的 array_rand
对于 y < 1000;是++; json_decode json 编码的字符串 - 计算时间
对于 y < 1000;是++;反序列化序列化的字符串 - 计算时间
回显更快的结果
平均而言:反序列化赢得了 96 次超过 json_decode 的 4 倍。在 2.5 毫秒内平均大约 1.5 毫秒。
我知道这已经很晚了,但是答案已经很老了,我认为我的基准测试可能会有所帮助,因为我刚刚在 PHP 7.4 中进行了测试
Serialize/Unserialize 比 JSON 快得多,占用更少的内存和空间,并且在 PHP 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
在此处查看结果(对于将 PHP 代码放入 JS 代码框中的黑客行为感到抱歉):
http://jsfiddle.net/newms87/h3b0a0ha/embedded/result/
结果:在 PHP 5.4 中,serialize()
和 unserialize()
在不同大小的数组上都明显更快。
我针对真实世界的数据制作了一个测试脚本,用于比较 json_encode 与 serialize 以及 json_decode 与 unserialize。测试在生产中电子商务网站的缓存系统上运行。它只是获取已经在缓存中的数据,并测试对所有数据进行编码/解码(或序列化/反序列化)的时间,并将其放在一个易于查看的表中。
我在 PHP 5.4 共享主机服务器上运行它。
结果非常明确,对于这些从大到小的数据集,序列化和反序列化是明显的赢家。特别是对于我的用例,json_decode 和 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>
首先,我更改了脚本以进行更多基准测试(并且还进行了 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) (built: Jan 18 2017 19:13:23) (NTS) Copyright (c) 1997-2016 The PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies with Zend OPcache v7.0.14,版权所有 (c) 1999-2016,由 Zend Technologies 提供
我的结果是:
serialize() (wins: 999) 比 json_encode() 快大约 10.98% unserialize() (wins: 987) 大约比 json_decode() 快 33.26% unserialize() (wins: 987) 比数组 json_decode 快大约 48.35% ()
很明显,serialize/unserialize 是最快的方法,而 json_encode/decode 是最便携的。
如果您考虑读取/写入序列化数据的频率是向非 PHP 系统发送或接收数据的 10 倍或更多的场景,那么您最好使用序列化/反序列化并在序列化之前使用 json_encode 或 json_decode在时间方面。
在做出最终决定之前,请注意 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
)
json_encode
编码的是一个关联数组,您可以轻松地将其强制返回到一个数组中,如下所示:$json = json_encode($some_assoc_array); $back_to_array = (array)json_decode($json);
另外值得注意的是,您可以访问对象与 PHP 中的数组方式相同,因此在典型场景中,人们甚至不知道其中的区别。不过好点!
如果您想备份数据并在另一台机器上或通过 FTP 恢复数据,JSON 会更好。
例如,如果您将数据存储在 Windows 服务器上,通过 FTP 下载并在 Linux 上恢复它,则使用序列化,由于字符重新编码,它无法再工作,因为序列化存储字符串的长度和 Unicode > UTF-8 对一些 1 字节字符进行转码可能会变成 2 字节长,从而导致算法崩溃。
THX - 对于这个基准代码:
我用于配置的数组的结果如下所示:JSON 编码为 0.0031511783599854 秒
PHP 序列化 0.0037961006164551 秒
json_encode()
大约比 serialize()
JSON 编码 0.0070841312408447 秒快 20.47%
PHP 序列化在 0.0035839080810547 秒内
unserialize()
比 json_encode()
快大约 97.66%
所以 - 在您自己的数据上进行测试。
如果总结人们在这里所说的话,json_decode/encode 似乎比 serialize/unserialize 更快,但是如果你做 var_dump,序列化对象的类型就会改变。如果出于某种原因您想保留类型,请使用序列化!
(尝试例如 stdClass 与数组)
序列化/反序列化:
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,这不是很好,对象信息丢失了...所以根据需要决定,特别是如果它不仅是数组...
我建议你使用 Super Cache,它是一种文件缓存机制,不会使用 json_encode
或 serialize
。与其他 PHP 缓存机制相比,它使用简单且速度非常快。
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();
?>
不定期副业成功案例分享
JSON_UNESCAPED_UNICODE
。json_encode
),它的平均速度比现在的序列化快 131%。因此,在 5.4.x 中,与 5.3.x 相比,该功能必须有一些相当不错的改进。具体来说,我在 CentOS 6 上运行 5.4.24。所以,为 JSON 好!PHP 在 0.093269109725952 秒内未序列化
json_decode() 比 unserialize() 快大约 39.99%
serialize() was roughly 35.04% faster than json_encode()