Вопрос для адванснутых пхпшников.
Мне нужно в строке таблицы БД хранить массив. Очевидно, что его надо как-то хитро упаковать. Массив многомерный, так что лучше всего упаковывать либо serialize'ом, либо хранить там PHP строку "array('key'=>'data',...)" и eval'ом потом её вытягивать в какую-то переменную. Мне важна скорость распаковки, т.е. сколько времени будет затрачено на перевод строки в array().
Вопрос заключается вот в чём: не приходилось ли кому-нибудь из вас хранить данные в таком виде (массив в виде строки) и какой наиболее быстрый способ распаковки данных в этом случае вы могли бы предложить ? (Скорость упаковки значения не имеет).
Примечание:
2 OneMoreDay:
Сразу видно, что не пхпшник.
Отвечаю. Предположим, у меня есть массив данных
$m = array(7,array(0,'',30,2),array(8,'hdr',32,16,'s'=>array(array(0,'',48,3),array(5,'content',51,20,'s'=>array(array(0,'',71,142),
array(1,'docnum',213,10),array(0,'',223,35),array(5,'searchform',258,23,'s'=>array(array(0,'',281,5),array(1,'search',286,10),
array(0,'',296,1),array(1,'subm',297,8),array(0,'',305,5))),array(0,'',334,20),array(5,'results',354,20,'s'=>array(array(0,'',374,79),
array(1,'search',453,10),array(0,'',463,26),array(1,'found',489,9),array(0,'',498,59),array(1,'pager',557,9),array(0,'',566,20),
array(5,'line',586,17,'s'=>array(array(0,'',603,90),array(1,'num',693,7),array(0,'',700,34),array(1,'_imgroot',734,12),array(0,'',746,11),
array(1,'icon',757,8),array(0,'',765,7),array(1,'filetype',772,12),array(0,'',784,22),array(1,'url',806,7),array(0,'',813,96),
array(1,'pathname',909,12),array(0,'',921,4),array(1,'filename',925,12),array(0,'',937,103),array(1,'description',1040,15),
array(0,'',1055,115),array(1,'date',1170,8),array(0,'',1178,15),array(1,'size',1193,8),array(0,'',1201,14),array(1,'folder',1215,10),
array(0,'',1225,164))),array(0,'',1407,20),array(1,'pager',1427,9),array(0,'',1436,20))),array(0,'',1477,6),
array(5,'no_result',1483,22,'s'=>array(array(0,'',1505,45),array(1,'search',1550,10),array(0,'',1560,68))),array(0,'',1651,30),
array(1,'_root',1681,9),array(0,'',1690,72))),array(0,'',1783,2))),array(0,'',1802,1));
Этот массив нужно целиком затолкать в строку и записать в БД. Искать по этому массиву, пока он лежит в БД, ничего не нужно. Просто когда мне он понадобится, я его считываю из БД и быстро распаковываю.
Вопрос в том, чтобы извлечение и распаковку делать максимально быстро.
Примечание:
Этот массив многоуровневый, генерируется скриптом на основе анализа некоего файла данных, поэтому записывать красиво в виде деревца мне было лень. Просто поверьте на слово.
Примечание:
Нужно ту строку, в которую будет упакован данный массив, быстро переводить обратно в переменную типа array(), т.е. чтобы можно было обращаться к нему и работать как с обычным массивом, например
echo $m[2]['s'][0][3];
Примечание:
2 OneMoreDay:
да, конечно, хранить так, как массив находится в памяти - идеальный вариант, потому что не придётся ничего преобразовывать в принципе. Но вся проблема в том, что у PHP, да и вообще скриптовых языков, нет понятия "память" в том виде, в котором она есть в Си и С++...
Как вариант - я уже писал выше - это хранить кусок кода, создающий массив, т.е. в естественном виде :) Но всё равно для его использования интерпретатору придётся его в байт-код перекомпилить... а это время.
Примечание:
2 Ильдар-:
Спасибо за практический подход. Я не стал тестировать работу конверторов на массивах разной длины, просто взял наиболее длинный из реальных мультиуровневых массивов, что у меня есть на текущий момент и произвёл сравнение. Также проверил работу и для JSON, так как кое-где в этих ваших интернетах пишут, что, дескать, json_decode() делает unserialize() чуть ли не в 2 раза по скорости. А вот и нифига подобного. Смотрите сами:
Compare encoded length:
eval: 3353
json: 2738
serialize: 7429
Compare decoding speed:
deeval: 0.42009353637695 ms
json_decode: 0.2448558807373 ms
unserialize: 0.048160552978516 ms
Видно налицо, что из соображений скорости мне однозначно лучше всего использовать unserialize() и не выдумывать всякие глупости. Хотя при этом длина закодированного массива получается в 2 с гаком раза больше. Но в моём случае это не шибко критично.