我应该使用关联数组还是对象?

时间:2011-12-14 00:18:49

标签: php arrays performance object

众所周知,json_decode为您提供了返回关联数组或对象的选项。在许多其他情况下我们也有两种选择。显然,在某些情况下,根据您正在处理的数据类型(与一个项目相关的一组数据与项目列表)相比,使用一个或另一个更“合适”。

我想知道的是,在内存,速度等方面,使用一方与另一方的效率有何不同?我对一个非常大的对象的访问时间特别感兴趣 - 与一个非常大的数组比较,为什么?

很抱歉,如果之前已经讨论过,搜索结果一无所获。我正在写一个基准,可能会告诉我哪一个更好,但不会帮助我理解原因。

3 个答案:

答案 0 :(得分:46)

许多程序员更喜欢使用true作为json_decode的第二个参数,因为返回的 assoc数组与您在javascript中处理对象的方式非常相似。

返回一个正确的对象需要阅读有关如何使用和不使用的对象,并且因为大多数程序员都非常熟悉更喜欢的关联数组,特别是如果代码将由开发人员团队维护。代码应易于理解。

关于表现的问题我不认为你需要担心,因为大多数(所有)案件的瓶颈都在其他地方。除非你正在解析一个巨大的字符串,并且我的意思是真的很大,你不应该做任何基准测试。我相信返回一个关联数组与一个合适的对象之间的区别很小。


效果基准(解析)

我发现了一个相当大的json字符串here并进行了一些调整以使其更大,最终大小为84 578字节。

然后我使用两个备选方案(关联数组与对象)解析字符串各1 000次,然后我运行测试三次。结果如下:

第一次运行

  JSON object exec: 4.06122 s
  JSON assoc  exec: 3.28679 s
-------------------------------------
assoc is faster by 19.07%

第二次

  JSON object exec: 4.09614 s
  JSON assoc  exec: 3.29216 s
-------------------------------------
assoc is faster by 19.63%

第三次

  JSON object exec: 4.08762 s
  JSON assoc  exec: 3.29960 s
-------------------------------------
assoc is faster by 19.28%

效果基准(读/写)

此基准测试用于显示stdObjectArray()中的哪一个更快,我使用的解析修改过的json文件(更大的一个)比以前的基准测试更好。

每次读/写测试都运行了100 000次(即,下面给出的代码执行了很多次)。

json_decode($ json_data)

for ($i =0; $i < 24; ++$i){
  $a = $object[$i]->user->profile_sidebar_border_color . "stackoverflow";
  $object[$i]->nested->entities->user_mentions[0]->indices[$i&1] += 1;
}

json_decode($ json_data,true)

for ($i =0; $i < 24; ++$i){
  $a = $assoc[$i]['user']['profile_sidebar_border_color'] . "stackoverflow";
  $assoc[$i]['nested']['entities']['user_mentions'][0]['indices'][$i&1] += 1;
}

第一次运行

  JSON object read/write: 3.05421 s
  JSON assoc  read/write: 2.51932 s
-------------------------------------
assoc is faster by 17.51%

第二次

  JSON object read/write: 3.06307 s
  JSON assoc  read/write: 2.52701 s
-------------------------------------
assoc is faster by 17.50%

第三次

  JSON object read/write: 3.06109 s
  JSON assoc  read/write: 2.52248 s
-------------------------------------
assoc is faster by 17.60%

PHP版

  

PHP 5.3.6(cli)(建于:2011年8月13日19:04:57)版权所有(c)1997-2011

     

PHP Group Zend Engine v2.3.0,版权所有(c)1998-2011 Zend

     

技术

答案 1 :(得分:4)

性能基准(访问时间)

这是我的基准。我最感兴趣的是访问时间。我用10,000个变量填充一个数组,把它作为一个对象,然后对于对象和数组,我只是访问其中一个变量10000次。部分代码:

$arr = array();
for( $i=0; $i<10000; $i++ ) {
    $arr['test'.$i] = 'Hello. My name is Inigo Montoya. You killed my father. Prepare to die.';
}
$obj = (object)$arr;

$tests = array(0,1000,2000,3000,4000,5000,6000,7000,8000,9999);

foreach( $tests as $test ) {
    $test_name = 'test'.$test;

    $start = microtime(true);
    for( $i=0; $i<10000; $i++ ) {
        $var = $obj->$test_name;
    }
    $end = microtime(true);
    $elapsed = $end - $start;

    $start = microtime(true);
    for( $i=0; $i<10000; $i++ ) {
        $var = $arr[$test_name];
    }
    $end = microtime(true);
    $elapsed = $end - $start;
}

<强>结果

我多次运行测试;这是典型的结果集之一;时间以毫秒为单位。

            Object    Array
------------------------------
test0       4.4880    4.1411
test1000    4.5588    4.2078
test2000    4.5812    4.2109
test3000    4.5240    4.2000
test4000    4.5800    4.2648
test5000    4.5929    4.2000
test6000    4.5311    4.2260
test7000    4.6101    4.2901
test8000    4.5331    4.1370
test9999    4.5100    4.1430

阵列平均比对象快8.3%(上面的集合中为7.7%)。我们尝试访问的变量的索引对访问时间没有影响。

看到上面的评论,我很尴尬地说我在使用PHP 5.3.4。

答案 2 :(得分:1)

不完全确定我的头脑,但你可以写一些简单的东西,然后使用FireFox的萤火虫来看看帖子的往返时间是几毫秒。