Все тесты выполнялись на одной машине (Intel Core i5-4440 3.1 ГГц,
DDR3 12 Гб) с одинаковыми настройками компиляторов (оптимизация -
максимальная производительность), в один поток. Тест заключается в
многократном выполнении сериализации и десериализации данных, тесты
запускались не менее 5 раз для получения усредненного времени. Исходный код доступен здесь.
Для тестов была использована следующая структура данных: class TicketSales { int shiftNumber; int cashRegister; time_t startShift; time_t endShift; voucher* vouchers; // Массив структур int numVouchers; // Размер массива, 2 или 1000 };
struct voucher { int voucher_number; double summ; char goods_name[128]; // Каждая строка 13-16 символов time_t time_of_sell; bool status; };
В
первом тесте массив структур vouchers состоял из 2 элементов (суммарно
92 байта полезных данных), во втором тесте - из 1000 (суммарно 35890
байт полезных данных). Ниже
приведены таблицы с результатами тестов.
Результаты тестирования
Тест 1: 92 байта полезных данных, 1000000 повторов
Не удалось найти URL спецификации гаджета
Тест 2: 35890 байт полезных данных, 10000 повторов
Не удалось найти URL спецификации гаджета
Комментарии к тестамUSDS
Для парсеров USDS был подготовлен следующий файл со словарем: USDS DictionaryUSDS DICTIONARY ID=888 v.1.0 { 1: STRUCT I { 1: UNSIGNED VARINT n; 2: DOUBLE s; 3: STRING<UTF-8> g; 4: LONG t; 5: BOOLEAN b; } RESTRICT {root=false;}
2: STRUCT S { 1: UNSIGNED VARINT n; 2: INT m; 3: LONG s; 4: LONG e; 5: ARRAY<I> v; } } Аналогичные
короткие имена структур и полей были в дальнейшем использованы для XML,
JSON и BSON. Для Protobuf были использованы аналогичные типы данных.
SAX-парсер
USDS по скорости превосходит DOM-парсер USDS примерно в 2 раза, но для
генерации SAX-парсера требуется приложить больше усилий. Protobuf 2
Для парсера Protobuf был подготовлен следующий proto-файл: Protobuf 2message ProtobufTicketSales { required int32 ShiftNumber = 1; required fixed32 CashRegister = 2; required fixed64 start_Shift = 3; required fixed64 end_Shift = 4;
message ProtobufVoucher { required int32 voucher_number = 1; required double summ = 2; required string goods_name = 3; required fixed64 time_of_sell = 4; required bool status = 5; } repeated ProtobufVoucher vouchers = 5; }
Парсер
работает очень быстро. USDS DOM-парсер превосходит Protobuf 2 по
скорости только благодаря использованию более качественного управления
памятью - Object Pool. Теоретическая максимальная производительность
парсера для Protobuf сопоставима с USDS. RapidJSON
В результате работы парсера JSON в первом тесте был получен следующий объект: JSON{ "T": { "n":1234, "r":9992828, "s":"1970.04.13 23:49:36", "e":"1970.04.14 00:26:39", "V": [ {"u":0,"m":0.0,"g":"Goods ID is 0","t":"1970.01.01 03:00:00","b":true}, {"u":1,"m":1.0,"g":"Goods ID is 1","t":"1970.01.01 03:00:01","b":false} ] } } SAX-парсер
от Rapidjson показывает относительно высокую скорость, но реализация
метода десериализации требует много усилий, и полученный код очень
тяжело отлаживать. TinyXML2
В результате работы парсера XML в первом тесте был получен следующий объект: XML<T> <S n="1234" r="9992828" s="1970.04.13 23:49:36" e="1970.04.14 00:26:39"/> <V> <I n="0" s="0" g="Goods ID is 0" t="1970.01.01 03:00:00" b="1"/> <I n="1" s="1" g="Goods ID is 1" t="1970.01.01 03:00:01" b="0"/> </V> </T>
Библиотека TinyXML2 очень легко встраивается в готовый проект, но сериализация работает крайне медленно. BSON
Результатом работы парсера BSON является бинарная последовательность, ее текстовое представление приведено ниже: BSON{ "T" : { "n" : 1234, "r" : 9992828, "s" : { "$numberLong" : "8887776" }, "e" : { "$numberLong" : "8889999" }, "V" : [ { "u" : 0, "s" : 0, "g" : "Goods ID is 0", "t" : { "$numberLong" : "0" }, "b" : true }, { "u" : 1, "s" : 1, "g": "Goods ID is 1", "t" : { "$numberLong" : "1" }, "b" : false } ] } }
Парсер BSON медленнее, чем USDS и Protobuf, т.к. ему приходится работать с текстовыми именами ключей. ASN.1
Для компилятора ASN.1 был подготовлен следующий файл правил: ASN.1AsnTest DEFINITIONS ::= BEGIN AsnVoucher ::= SEQUENCE { voucherNumber INTEGER, summ REAL, goodsName UTF8String, timeOfSell UTCTime, status BOOLEAN }
AsnTicketSales ::= SEQUENCE { shiftNumber INTEGER, cashRegister INTEGER, startShift UTCTime, endShift UTCTime, vouchers SEQUENCE OF AsnVoucher } END
Стандарт
был протестирован в режимах BER, PER, OER и XER. Последний вариант -
самый медленный, т.к. фактически представляет собой XML, результат
данной сериализации приведен ниже: ASN.1 XER<?xml version="1.0" encoding="UTF-8"?> <AsnTicketSales> <shiftNumber>1234</shiftNumber> <cashRegister>9992828</cashRegister> <startShift>700413234936Z</startShift> <endShift>700414002639Z</endShift> <vouchers> <AsnVoucher> <voucherNumber>0</voucherNumber> <summ>0</summ> <goodsName>Goods ID is 0</goodsName> <timeOfSell>700101030000Z</timeOfSell> <status><true/></status> </AsnVoucher> <AsnVoucher> <voucherNumber>1</voucherNumber> <summ>1.0E0</summ> <goodsName>Goods ID is 1</goodsName> <timeOfSell>700101030001Z</timeOfSell> <status><false/></status> </AsnVoucher> </vouchers> </AsnTicketSales>
Парсер
работает довольно медленно, вероятно это связано с использованием
trial-лицензии. Теоретическая максимальная производительность парсера
ASN.1 сопоставима с Protobuf и USDS.
2015.11.02 Андрей Абрамов
 CommentsНе удалось найти URL спецификации гаджета
|