我需要在平面文件中存储多维数据关联数组,以便进行缓存。我可能偶尔会遇到需要将其转换为JSON以在我的web应用程序中使用,但绝大多数情况下,我将直接在PHP中使用数组。
在这个文本文件中将数组存储为JSON还是PHP序列化数组更有效?我查看了一下,似乎在最新版本的PHP(5.3)中,json_decode实际上比反序列化更快。
我目前倾向于将数组存储为JSON,因为我觉得如果有必要的话,它更容易被人阅读,它可以在PHP和JavaScript中使用,而且从我所读到的,它甚至可能更快地解码(虽然不确定编码)。
有人知道有什么陷阱吗?有人有好的基准来显示这两种方法的性能优势吗?
我知道这有点晚了,但答案很旧,我想我的基准测试可能会有帮助,因为我刚刚在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
UnSerialize Time: 0.19309520721436
Var导出和包括:3.1974139213562
JSON解码内存:16384
反序列化内存:14360
Var Export and Include: 192
我知道这有点晚了,但答案很旧,我想我的基准测试可能会有帮助,因为我刚刚在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
UnSerialize Time: 0.19309520721436
Var导出和包括:3.1974139213562
JSON解码内存:16384
反序列化内存:14360
Var Export and Include: 192
您可能还会对https://github.com/phadej/igbinary感兴趣——它为PHP提供了一个不同的序列化“引擎”。
我的随机/任意的“性能”数据,使用PHP 5.3.5在64位平台上显示:
JSON:
JSON编码在2.180496931076秒
JSON解码在9.8368630409241秒
serialized "String" size: 13993
原生PHP:
PHP在2.9125759601593秒内序列化
PHP在6.4348418712616秒内反序列化
序列化的“字符串”大小:20769
Igbinary:
winigbinary在1.6099879741669秒内序列化
winigbinary在4.7737920284271秒内未序列化
WIN序列化的“字符串”大小:4467
因此,igbinary_serialize()和igbinary_unserialize()更快,使用更少的磁盘空间。
我使用fillArray(0,3)代码,但使数组键更长的字符串。
igbinary可以存储与PHP原生序列化相同的数据类型(所以对象等没有问题),如果你愿意,你可以告诉PHP5.3使用它来进行会话处理。
参见http://ilia.ws/files/zendcon_2010_hidden_features.pdf -特别是幻灯片14/15/16
在你做出最终决定之前,请注意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_decode/encode似乎比序列化/反序列化BUT更快
如果执行var_dump,序列化对象的类型将被更改。
如果出于某种原因想要保留类型,请使用serialize!
(例如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,这不是很好,对象信息丢失…所以根据需要来决定,特别是如果它不仅仅是数组……