All tests were performed on the same computer (Intel Core i5-4440 3.1
GHz, DDR3 12 GB) with the same compiler configuration (optimization -
maximum performance), in one thread. The test performs multiple
serialization and deserialization of the data structure. The test were
performed several times to obtain the an average time.
The source code is provided here.
The following data structures were used:
class TicketSales
{
int shiftNumber;
int cashRegister;
time_t startShift;
time_t endShift;
voucher* vouchers;
int numVouchers;
};
struct voucher
{
int voucher_number;
double summ;
char goods_name[128];
time_t time_of_sell;
bool status;
};
The first test includes the array "vouchers", containing two elements
"voucher"; the amount of useful data is 92 bytes. In the second test,
the array’s size is 1000 elements and the amount of useful data is
35,890 bytes. The tests results are shown below. The source code can be
provided upon request.
Test Results
Test 1: 92 bytes of useful data, 1,000,000 passes
The gadget spec URL could not be found
Test 2: 35890 bytes of useful data, 10,000 passes
The gadget spec URL could not be found
Comments to the Tests
USDS
The next dictionary was prepared for the USDS test:
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;
}
}
The same names for tags and fields were used in XML, JSON and BSON testes. The same data types were used in Protobuf test.
SAX parser is twice faster then DOM parser, but it requires more efforts from developers.
Protobuf 2
The next proto-file was prepared for Protobuf test:
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;
}
The parser works very quickly. USDS DOM parser works quicker only
because the pattern "Object pull" is used. In theory, Protobuf parser
can work with the same speed.
RapidJSON
The next result was received from JSON parser:
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}
]
}
}
Rapidjson SAX parser works relatively quickly, but it's required a lot
of efforts from developer: it's very difficult to debug source code.
TinyXML2
The next result was received from XML parser:
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>
It's very simple to integrate the library TiniXML2 to the project but it works too slowly.
BSON
The result of BSON parser is binary data, but it can be represented as the next JSON object:
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 parser works slower then USDS and Protobuf because it uses text names for keys.
ASN.1
The next rule-file was prepared for ASN.1 test:
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
The parser was tested in BER, PER, OER and XER formats. XER is slowest
because it's based on XML. The result from XER parser represented below:
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>
All ASN.1 parsers work slow, perhaps it's related to trial-license. In
theory, ASN.1 parser can work as fast as USDS and Protobuf.
2015.11.03 Andrey Abramov