对JSON对象数组进行排序:我应该使用`json_decode`还是`preg_match`?

时间:2017-11-06 15:00:58

标签: php json performance sorting

我有一个json编码对象数组,我需要根据每个对象的一个​​属性进行排序,使用传递给usort的自定义比较函数。数据看起来像这样:

[
  '{"property-to-sort-by":"value1"}', 
  '{"property-to-sort-by":"value2"}',
  ...
]

我可以通过两种方法在比较函数中提取此属性:

  1. json_decode每个对象并比较属性。
  2. 使用preg_match提取要比较的属性(每个对象一个属性)。
  3. 哪种方法效果更好,还是有其他方法我还没有想过会更高效?

2 个答案:

答案 0 :(得分:2)

TLDR:鉴于只需要从每个对象中提取一个属性,我发现preg_match对于排序json编码数组的效率明显高于json_decode对象。

首先,我将我能想象的最简单的比较函数作为参考点进行基准测试:

$s = microtime();
usort($jsonArray, function($a, $b) {
    return 1;
});
$p = microtime() - $s;
var_dump($p);

这个简单的案例将我的测试列表排序在0.0002微秒以上。以下是我的10次试用时间:

0.00022999999999995
0.00022800000000001
0.00022800000000001
0.00023300000000004
0.000217
0.00023899999999999
0.00021699999999999
0.00023000000000001
0.000251
0.00021499999999999

接下来,我对json_decode方法进行了基准测试:

$s = microtime();
usort($jsonArray, function($a, $b) {
    $aOrg = \json_decode( $a );
    $bOrg = \json_decode( $b );
    return strcasecmp($aOrg->name, $bOrg->name);
});
$p = microtime() - $s;
var_dump($p);

此函数按我的列表排序约0.0008或0.0009毫秒:

0.00081499999999995
0.00096299999999999
0.000973
0.00081300000000001
0.00081299999999999
0.00084399999999996
0.000931
0.000875
0.000997
0.00081000000000009

最后,我测试了preg_match方法:

$s = microtime();
usort($jsonArray, function($a, $b) {
    preg_match('/"name":"(.+?)"/', $a, $aMatches);
    preg_match('/"name":"(.+?)"/', $b, $bMatches);
    $aName = $aMatches[1];
    $bName = $bMatches[1];
    return strcasecmp($aName, $bName);
});
$p = microtime() - $s;
var_dump($p);

这种方法在我的列表中排序大约0.0004毫秒:

0.00047700000000001
0.000448
0.00044799999999995
0.00046199999999996
0.00045200000000001
0.00044999999999995
0.000448
0.000585
0.00045100000000001
0.000449

总之,对于我的测试列表,与使用preg_match相比,使用json_decode排序的时间大约比使用return 1少三分之一,而不是简单的server { listen 80; server_name myprojecy.xyz; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; location / { root /var/www/html/project-forlder/app/webroot; index index.php index.html index.htm; if (-f $request_filename) { break; } if (-d $request_filename) { break; } rewrite ^(.+)$ /index.php?q=$1 last; } location ~ .*\.php[345]?$ { include /etc/nginx/fastcgi.conf; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/html/project-forlder/app/webroot$fastcgi_script_name; } 实现。

答案 1 :(得分:1)

这是一种可能更好的方法:

$array = json_decode("[".implode(",",$jsonArray)."]");
usort($jsonArray2, function($a, $b) {
    return strcasecmp($a->name, $b->name);
});

我确实对此here进行了一些测试,但我仍然感到困惑的是为什么这似乎比基线表现得更快。