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

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

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

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

Многие программисты предпочитают использовать 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% 

3-й запуск

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

Performance Benchmark (чтение / запись)

Этот тест должен показать, какой из 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% 

3-й запуск

  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

технологии

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.

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