我需要在平面文件中存储多维数据关联数组,以便进行缓存。我可能偶尔会遇到需要将其转换为JSON以在我的web应用程序中使用,但绝大多数情况下,我将直接在PHP中使用数组。
在这个文本文件中将数组存储为JSON还是PHP序列化数组更有效?我查看了一下,似乎在最新版本的PHP(5.3)中,json_decode实际上比反序列化更快。
我目前倾向于将数组存储为JSON,因为我觉得如果有必要的话,它更容易被人阅读,它可以在PHP和JavaScript中使用,而且从我所读到的,它甚至可能更快地解码(虽然不确定编码)。
有人知道有什么陷阱吗?有人有好的基准来显示这两种方法的性能优势吗?
如果总结一下人们在这里所说的话,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,这不是很好,对象信息丢失…所以根据需要来决定,特别是如果它不仅仅是数组……
这取决于你的优先级。
如果性能是你的绝对驾驶特点,那么无论如何要用最快的。在你做出选择之前,一定要充分了解它们之间的差异
Unlike serialize() you need to add extra parameter to keep UTF-8 characters untouched: json_encode($array, JSON_UNESCAPED_UNICODE) (otherwise it converts UTF-8 characters to Unicode escape sequences).
JSON will have no memory of what the object's original class was (they are always restored as instances of stdClass).
You can't leverage __sleep() and __wakeup() with JSON
By default, only public properties are serialized with JSON. (in PHP>=5.4 you can implement JsonSerializable to change this behavior).
JSON is more portable
可能还有其他一些不同之处,我现在想不出来。
一个简单的速度测试来比较两者
<?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';
}