Дошли, наконец, руки поставить и протестировать PHP-расширение Igbinary, о котором сегодня и поведую.
Igbinary предназначена для замены стандартных механизмов сериализации. Сериализация, это, как все наверное знают, способ представления структуры данных в виде строки, годной для хранения, передачи и последующей конвертации обратно в изначальную структуру.
$A = array(1, 2, 'three', true); $s = serialize($A); var_dump($s); // 'a:4:{i:0;i:1;i:1;i:2;i:2;s:5:"three";i:3;b:1;}' |
Для подобных действий используются функции serialize() и unserialize. Кроме того сериализация происходит неявно для данных сессий, значений в мемкэше и др.
Основной недостаток стандартной сериализации: формат строки — слишком многословный. Именно эту проблему решает Igbinary, сохраняя данные в компактной двоичной последовательности.
Установка
На nix’ах всё просто. Идём на сайт расширения, скачиваем tar.gz
, и всё как обычно: tar, phpize, configure, make, make install, extension=igbinary.so
.
Для Windows, к сожалению, версии не нашёл.
Использование
Просто вместо serialize/unserialize
используем igbinary_serialize()
и igbinary_unserialize()
.
Для того, чтобы сессии сериализовали свои данные через Igbinary, в php.ini пишем:
session.serialize_handler=igbinary |
Чтобы заставить это работать и для мемкэша, в теории нужно собрать php_memcached с --enable-memcached-igbinary
, и установить опцию OPT_SERIALIZER. У меня правда с первых двух раз php_memcached не собрался, а третий раз я пытаться не стал, так что отвечать за это не могу.
Ну и следует учитывать, что если у вас в мемкэше уже лежат данные, сериализованные дедовским способом, после подключения Igbinary, вытащить их будет проблемно.
Тестирование
Тестировалось на Ubuntu 9.10, PHP 5.3.2-dev
Результаты для Integer:
Integer Serialize Igbinary / Time ser 167 ms 82 ms 2,0 Time unser 111 ms 100 ms 1,1 Size 1 737 706 2,5 Bytes / El 17,4 7,1 Integer Small Serialize Igbinary / Time ser 143 ms 71 ms 2,0 Time unser 99 ms 83 ms 1,2 Size 991 406 2,4 Bytes / El 9,9 4,1 Integer Big Serialize Igbinary / Time ser 143 ms 75 ms 1,9 Time unser 116 ms 84 ms 1,4 Size 1 798 706 2,5 Bytes / El 18,0 7,1 |
Сериализовались массивы из 100 элементов (по 1000 циклов на тест).
Integer
— числа по рандому, Integer Small
— числа до 100, Integer Big
— числа более 1 000 000 000.
Как видно, сериализует Igbinary, практически, вдвое быстрее. Десериализует тоже шустро. Но главное, что нас интересует, это размер получившейся строки.
Так как стандартный serialize сохраняет числа в виде строки, то очевидно, чем большего порядка число, тем длинее его представление. «0» займёт 4 байта («i:0;»), «10» уже 4. Для массива в тесте Integer Big приходится по 18 байт на элемент.
Igbinary же мало того, что хранит всё в двоичном виде, так и использует не один тип iteger (в 4 байта), а разные в зависимости от числа. Если число можно хранить в 1 байте, то хранится в 1 байте.
В итоге Igbinary сжимает данные в 2,5 раза лучше, чем serialize.
Float Serialize Igbinary / Time ser 1 388 ms 74 ms 18,9 Time unser 868 ms 86 ms 10,1 Size 5 650 1 085 5,2 Bytes / El 56,5 10,9 |
Теперь float. Здесь с serialize() вообще мрак кромешный. Он пытается вытащить из двоичного представления в памяти все возможные разряды и сохранить их: 1/3
= 'd:0.333333333333333314829616256247390992939472198486328125;'
. А так как igbinary сам двоичный, ему проще.
В итоге 5-кратное преимущество по размеру и 20-кратное по скорости.
String Serialize Igbinary / Time ser 147 ms 205 ms 0,7 Time unser 120 ms 121 ms 1,0 Size 2 798 1 891 1,5 Bytes / El 28,0 18,9 String-Keys Serialize Igbinary / Time ser 157 ms 321 ms 0,5 Time unser 160 ms 155 ms 1,0 Size 4 066 2 877 1,4 Bytes / El 40,7 28,8 |
String
— порядковый массив строк, String-Keys
— ассоциативный массив со строковыми ключами.
Строки, они и в Африке строки, и имеют одно и тоже представление для обоих «сериализаторов». Igbinary выигрывает за счёт более компактной служебной информации. Здесь много зависит от величины строк, чем длинее строка, тем меньше будет разница в размерах.
Обращает на себя внимание, что по скорости стандартные средства на этот раз обошли Igbinary.
Резюме
Вобщем, Igbinary отличная приблуда. Пользуйтесь и не пожалеете, если у вас, конечно, не винда.
ахуенчег чуваг! уже устанавливаю
phpdude, 27.05.2010, 12:18
Полезная штука
adw0rd, 27.05.2010, 12:27
Нужно поюзать
Dead, 28.08.2010, 20:15
cd /usr/ports/converters/igbinary; make install clean;
Pandora, 24.10.2010, 14:55
Pandora, да, можно и так, если фря :)
vasa_c, 24.10.2010, 15:22
Спасибо за ссылку на расширение, стандартный serialize — унылое говно
Денис Радченко, 30.01.2011, 11:32
Все разительно меняется если выключить igbinary.compact_strings:
http://bolknote.ru/2013/10/19/~4082/
Константин, 19.10.2013, 20:35
Ну, не так чтобы всё меняется, но забавно.
Хотя, имхо, при сериализации важнее конечный объём, а не скорость.
vasa_c, 20.10.2013, 11:15