Подтвердить что ты не робот

Должен ли я использовать ассоциативный массив или объект?

Как мы все знаем, json_decode дает вам возможность возвращать ассоциативный массив или объект. Есть много других ситуаций, когда у нас есть два варианта. Очевидно, что в некоторых случаях использование одного или другого более "целесообразно" на основе типа данных, с которыми вы имеете дело (группа данных, относящихся к одному элементу, и список элементов).

Мне интересно, есть ли разница в эффективности использования одного и другого с точки зрения памяти, скорости и т.д.? Меня особенно интересует время доступа для очень большого объекта - как это сравнивается с очень большим массивом и почему?

Извините, если это было обсуждено ранее, поиск не появился. Я пишу бенчмарк, который может сказать мне, какой из них лучше, но не поможет мне понять, почему.

4b9b3361

Ответ 1

Многие программисты предпочитают использовать true как второй аргумент json_decode, поскольку возвращаемый массив-помощник будет очень похож на то, как вы обрабатываете объекты в javascript.

Возврат надлежащего объекта потребует чтения о том, как это используется, а что нет, и поскольку большинство программистов хорошо знакомы с ассоциативными массивами, которые более предпочтительны, особенно если код будет поддерживаться командой разработчиков. Код должен быть легко понятным.

Что касается вопросов о производительности, я не думаю, что вам нужно будет беспокоиться об этом, поскольку бутылка шеи в большинстве (всех) случаях будет в другом месте. Если вы не разбираете массивную строку, и я имею в виду действительно огромную, вам не нужно делать никаких тестов. Я полагаю, что разница между возвратом массива-ассоциатора и соответствующим объектом будет незначительной.


Тест производительности (синтаксический анализ)

Я нашел довольно большую строку json здесь и внес некоторые корректировки, чтобы сделать его еще большим, конечный размер - 84 578 байт.

Затем я проанализировал строку, используя обе альтернативы (ассоциативный массив против объекта) по 1 000 раз каждый, и я провел тест три раза. Результаты приведены ниже:

1-й прогон

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

2-й прогон

  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%

Тест производительности (чтение/запись)

Этот тест должен показать, какой из stdObject и Array() работает быстрее, я использую модифицированный 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;
}

1-й прогон

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

2-й прогон

  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) (построено: 13 авг 2011 19:04:57) Copyright (c) 1997-2011

PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend

Технологии

Ответ 2

Performance Benchmark (время доступа)

Вот мой бенчмарк. Меня больше всего интересовало время доступа. Я заполнил массив с 10 000 переменных, бросил его как объект, затем для объекта и массива я просто обратился к одной из переменных 10 000 раз. Часть кода:

$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.

Ответ 3

Не совсем уверен в верхней части моей головы, но вы можете написать что-то простое, а затем использовать FireBug FireFox, чтобы узнать, что в оба конца сообщения было в ms.