存储PHP数组的首选方法(json_encode与序列化)


609

我需要在平面文件中存储多维关联数据数组以进行缓存。我可能偶尔会遇到需要将其转换为JSON以便在我的Web应用程序中使用的情况,但是绝大多数时候,我将直接在PHP中使用该数组。

在此文本文件中将数组存储为JSON或PHP序列化数组会更有效吗?我环顾四周,似乎在最新版本的PHP(5.3)json_decode中实际上比快unserialize

我目前倾向于将数组存储为JSON,因为如果有必要,我认为它很容易被人阅读,并且可以不费吹灰之力就可以在PHP和JavaScript中使用,从我的阅读中来看,它甚至可能是解码速度更快(不过不确定编码)。

有人知道有什么陷阱吗?任何人都有良好的基准可以显示这两种方法的性能优势?

Answers:


563

取决于您的优先级。

如果性能是您的绝对驾驶特性,那么请务必使用最快的一种。做出选择之前,只需确保您对差异有充分的了解

  • 不同于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';
}

31
“ JSON将UTF-8字符转换为Unicode转义序列。” 不再必须正确:我们现在有了JSON_UNESCAPED_UNICODE
TRiG 2012年

32
在这里快将近5年了,我又进行了测试(只是json_encode),平均速度比现在序列化快131%。因此,相对于5.3.x,在5.4.x中必须对该功能进行一些相当不错的改进。具体来说,我在CentOS 6上运行5.4.24。所以,对JSON来说是这样!
KyleFarris 2014年

8
在我的情况下,我们只编码一次并进行大量解码,因此我们对json_decode和unserialize进行了基准测试,结果是在0.06662392616272秒内对JSON进行了dcode编码。<br> PHP在0.093269109725952秒内未序列化了PHP <br> json_decode()大约比unserialize()快了39.99%
AMB

21
有趣的是:如果您在3v4l.org上运行此代码,则最新的PHP7开发版本的序列化运行速度比json_encode快:“ serialize()比json_encode()快76.53%”
marcvangend 2015年

21
2017年,PHP 7.1和serialize() was roughly 35.04% faster than json_encode()
Elias Soares

239

JSON比PHP的序列化格式更简单,更快,因此应使用JSON,除非

  • 您正在存储深层嵌套的数组:: json_decode()“如果JSON编码的数据深于127个元素,则此函数将返回false。”
  • 您正在存储需要反序列化为正确类的对象
  • 您正在与不支持json_decode的旧PHP版本进行交互

12
好答案。哈哈,深127级,似乎有点疯狂;值得庆幸的是,我最多只能参加2-3次比赛。您是否有任何数据可以支持json_decode / json_encode比反序列化/序列化更快的事实?
KyleFarris

1
我之前做了测试,并且json更快地发布了-尽管我不再有数据。
格雷格,

47
“ 5.3.0添加了可选深度。默认递归深度从128增加到512”
giorgio79 2011年

4
我还要在上面的列表中添加一个项目:如果您的数据可能包含无效的UTF-8字节序列,则不应使用json_encode()。对于此类数据,它仅返回false。例如尝试:var_dump(json_encode(“ \ xEF \ xEF”));
pako 2015年

1
总的来说,它更快是不正确的。如果您有一个约500个条目的小型数组,那么反序列化/序列化实际上要比json_decode / json_encode(PHP 5.6.19)快200-400%-Adam
Adam

59

我已经写了一篇有关该主题的博客文章:缓存大型数组:JSON,序列化还是var_export?。在这篇文章中,显示了序列化是小型到大型阵列的最佳选择。对于非常大的数组(> 70MB),JSON是更好的选择。


8
该链接不再可用。
2015年

1
谢谢,驼鹿,我已经更新了链接。尽管该文章已有6年历史了,对于当前的PHP版本可能不太准确。
塔可

我做了一些测试,并做了一个简单的函数来测试它,使用大数组(使用了Peter Bailey的函数)比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%。我的函数取所有迭代的平均时间并进行比较。我可能会在这里将其作为答案之一
MiChAeLoKGB,2015年

如果数据仅由PHP使用,则var_export是我的事情。只需要小心包含思想中可能出现的语法错误。
Gfra54

3
博客不再存在
popeye

53

您可能还对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-幻灯片14/15/16


25

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编码更快,并且生成的字符串更小,但是反序列化对字符串进行解码的速度更快。


6
我不知道为什么人们总是对这么小的数据集进行性能测试。这样一来,您将承担所有会增加错误结果的开销。如果人们对性能感兴趣,那可能是因为他们拥有非常大的数据集,因为一次获取​​微秒是没有意义的。
Yann Sagon 2012年

1
我经常会遍历许多小型数据集。对于数百个小型数据集,每个数据集获得1mS仍然很有趣。
Teson

@YannSagon即使使用小的数据集,进行性能测试也是有意义的。在测试之前您应该如何知道是否只有大约1微秒?
亚当


12

我扩大了测试范围,以包括反序列化性能。这是我得到的数字。

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似乎编码速度更快,但解码速度却很慢。因此,这可能取决于您的应用程序以及您最希望做什么。


9

主题非常好,阅读了一些答案后,我想分享有关该主题的实验。

我有一个用例,几乎每次我与数据库对话时都需要查询一些“巨大”表(不要问为什么,只是一个事实)。数据库缓存系统不合适,因为它不会缓存不同的请求,因此我还是讲有关PHP缓存系统。

我试过了,apcu但是不符合需求,在这种情况下内存不够可靠。下一步是通过序列化将其缓存到文件中。

该表有14355个条目,其中有18列,这些是我在读取序列化缓存时的测试和统计信息:

JSON:

众所周知,json_encode/ 的主要不便之处json_decode在于它将所有内容转换为StdClass实例(或对象)。如果需要循环,将其转换为数组可能是您要做的,是的,这增加了转换时间

平均时间:780.2毫秒;内存使用:41.5MB;快取档案大小:3.8MB

消息包

@hutch提到msgpack。漂亮的网站。让我们尝试一下吧?

平均时间:497毫秒;内存使用:32MB;快取档案大小:2.8MB

更好,但是需要新的扩展。有时会编译恐惧的人...

Ig二进制

@GingerDog提到igbinary。请注意,我设置了,igbinary.compact_strings=Off是因为我更关心阅读性能而不是文件大小。

平均时间:411.4毫秒;内存使用:36.75MB;缓存文件大小:3.3MB

比味精包更好。尽管如此,这也需要编译。

serialize/unserialize

平均时间:477.2毫秒;内存使用: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年

因为它很慢。我没有对此进行测试,但是我认为简单地从php强制更改类型会更快。
soyuka 2014年

我只知道创建数组比PHP中的对象快得多。
Alex Yaroshevich 2014年

因此,您在说的是json_decode($object, true),基本上,它的功能与(array) json_decode($object)递归操作相同,这将是相同的行为,并且在两种情况下都将产生巨大的成本。请注意,我尚未测试StdClass和之间的性能差异,array但这并不是重点。
soyuka 2014年

我确定这是另一笔费用,因为它是在没有对象的较低级别完成的。
Alex Yaroshevich 2014年

8

似乎序列化是我要使用的一种,其原因有两个:

  • 有人指出,反序列化比json_decode更快,并且“读”情况比“写”情况更有可能。

  • 当字符串包含无效UTF-8字符时,我遇到了json_encode的麻烦。发生这种情况时,字符串最终将为空,从而导致信息丢失。


能否请您用一个例子阐述你的最后一点
纳文Saroye

6

我已经在一个相当复杂的,轻度嵌套的,包含各种数据(字符串,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 2013年

6

我也做了一个小基准。我的结果是一样的。但是我需要解码性能。我注意到的地方,就像上面的几个人所说的那样,unserialize比还要快json_decodeunserialize大约需要60-70%的json_decode时间。因此结论很简单:当您需要编码json_encode性能时,请使用,当您需要解码性能时,请使用unserialize。由于无法合并这两个功能,因此必须在需要更高性能的地方选择。

我的伪基准测试:

  • 用一些随机键和值定义数组$ arr
  • x <100; x ++; 序列化并json_encode一个$ arr的array_rand
  • 对于y <1000; y ++; json_decode json编码的字符串-计算时间
  • 对于y <1000; y ++; 反序列化序列化的字符串-计算时间
  • 回显更快的结果

平均而言:反序列化在json_decode的4倍中赢得了96倍。平均间隔1.5毫秒超过2.5毫秒。


3

在做出最终决定之前,请注意,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

30
@toomuchphp,对不起,但您错了。json_decode的第二个参数'bool $ assoc = false'使json_decode产生一个数组。@KyleFarris,这也应该比使用类型转换数组更快。
janpio 2010年

答案不正确。当使用true作为函数的第二个参数时,json_decode()将返回关联数组而不是对象。
Marvin Saldinger

3

首先,我更改了脚本以进行更多基准测试(也可以运行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 The PHP Group Zend Engine v3.0.0,版权所有(c)1998-2016 Zend Technologies with Zend OPcache Zend Technologies v7.0.14,版权所有(c)1999-2016

我的结果是:

serialize()(wins:999)比json_encode()快10.98%,unserialize()(wins:987)比json_decode()unserialize()(wins:987)快大约33.26%,比数组json_decode快48.35% ()

所以显然,序列化/反序列化是最快的方法,而json_encode /解码是最便携的。

如果您考虑的情况是,序列化数据的读取/写入次数是非PHP系统的10倍或更多,则最好还是使用序列化/反序列化,并在序列化之前将其设为json_encode或json_decode就时间而言。


2

在这里查看结果(很抱歉,将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>

1

只是一个麻烦-如果您想将数据序列化为易于读取和理解的内容(例如JSON),但具有更高的压缩率和更高的性能,则应该签出messagepack。


2
如果只是fyi,最好将其作为注释。
technophyle

0

如果要备份数据并在其他计算机上或通过FTP还原数据,则JSON更好。

例如,对于序列化,如果您将数据存储在Windows服务器上,请通过FTP下载数据,然后在Linux上进行还原,由于charachter重新编码,该数据将不再起作用,因为序列化将字符串的长度存储在Unicode中>对1个字节的字符进行UTF-8转码可能会变成2个字节长,从而导致算法崩溃。


0

THX-此基准代码:

我的阵列我使用了配置结果如休耕:JSON在0.0031511783599854秒编码
PHP连载0.0037961006164551秒
json_encode()粗略20.47%的速度比serialize() JSON在0.0070841312408447秒编码
PHP连载0.0035839080810547秒
unserialize()粗略97.66%的速度比json_encode()

因此-根据您自己的数据进行测试。


您是说“ unserialize()中的json_decode()比json_encode()快约97.66%,是吗?
Meezaan-ud-Din 2014年

0

如果要总结一下人们在这里所说的话,那么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

-3

我建议您使用超级缓存,这是一种不会使用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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.