Проекты‎ > ‎USDS‎ > ‎

Тесты производительности

Все тесты выполнялись на одной машине (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 Dictionary

USDS 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 2

message 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.1

AsnTest 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 Андрей Абрамов
CC BY 4.0

Comments

Не удалось найти URL спецификации гаджета