1 Star 0 Fork 27

flw7887/DirectStruct

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README-EN 22.67 KB
一键复制 编辑 原始数据 按行查看 历史
calvinwilliams 提交于 2014-09-08 20:23 . UPDATE TO V1.0.3F
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
DirectStruct - C Structure Tools
1.Overview
DirectStruct is a C struct tool, command-line tool 'dsc' based on IDL definition file, generate the C structure definition and the corresponding code automatically, use directly in order to improve the development efficiency in applications, avoid the risk of development of redundancy and coding.
What automation code DirectStruct generated ?
* C structure definition
* Default batch Initialize function
* Network/host byte ordering functions
* Serialization/deserialization functions ( without or with compression )
* Print all field value functions in structure or output to your own log stream
What to do with DirectStruct ?
* C structure communication exchange directly : Threw the C structure variables directly by TCP between the specific platform to the other pair is a tempting idea, There is one problem about byte-order sequence of integer field, manual coding is a redundant thing, DirectStruct can help you automate the process. solve the problem of the byte-order directly in the exchange of messages , to avoid packaging before communication sent and unpacking after communications received , so very fast, is a message format for extreme performance in some scenes.
* Structure serialization/deserialization : In the cross-platform , it is not applicable for sending structure directly, don't worry, use DirectStruct generated serialization/deserialization function, although much packaging solution package, but after careful design and algorithm optimization, performance is also very attractive. If you enable compression options, binary data block greatly narrowed, facilitate communication exchange.
* Fast printing all field values in structure : for a large structure, dumping it is a boring thing, you can use DirectStruct helps you to automatically generate log function, output to the screen, or your own log stream.
* ( new idea increasing ... tell me what you need )
Why use DirectStruct ?
* Flexible struct defined syntax : command line tools 'dsc' read definition file, generate automation code, supports sub struct nested, struct array, such as the definition file contains the flexible configuration mode.
* Cross-platform : DirectStruct supports WINDOWS, Linux, AIX , such as the 64-bits integer, the standard IDL definition file will generate different platforms standard.
2.Install with compiling
for Linux
$ tar xvzf dsc-1.0.3.tar.gz
$ cd dsc-1.0.3/src
$ su
# make -f makefile.Linux clean
rm -f util.o
rm -f main.o
rm -f dsc.o
rm -f ReadDscFile.o
rm -f GenerateCCode.o
rm -f dsc
# make -f makefile.Linux install
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c util.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c main.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c dsc.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c ReadDscFile.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c GenerateCCode.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -o dsc util.o main.o dsc.o ReadDscFile.o GenerateCCode.o -L.
cp -f dsc /usr/bin/
3.Basic use
3.1.Write a IDL definition file , Use the tools 'dsc' processing it and generate automation code
[code]
$ cat IDL_AllTypes.dsc
STRUCT AllTypes
{
INT 1 n1
INT 2 n2
INT 4 n4
INT 8 n8
UINT 1 u1
UINT 2 u2
UINT 4 u4
UINT 8 u8
FLOAT 4 f4
FLOAT 8 f8
CHAR 1 ch
UCHAR 1 uch
STRING 32 str32
STRING 1024 str1024
}
$ dsc -f IDL_AllTypes.dsc -c
STRUCT AllTypes
INT 1 n1
INT 2 n2
INT 4 n4
INT 8 n8
UINT 1 u1
UINT 2 u2
UINT 4 u4
UINT 8 u8
FLOAT 4 f4
FLOAT 8 f8
CHAR 1 ch
UCHAR 1 uch
STRING 32 str32
STRING 1024 str1024
ok!
$ ls
IDL_AllTypes.dsc
IDL_AllTypes.dsc.h
IDL_AllTypes.dsc.c
IDL_AllTypes.dsc.LOG.c
[/code]
IDL_test.dsc.h contains the C structure definition.
IDL_test.dsc.c contains the default initialization function, network/host byte ordering functions, and serialization/deserialization functions.
IDL_test.dsc.LOG.c contains a log function is used to print a message all fields to the standard output or your own log stream for debugging.
Note: test/makefile not contains processing .dsc definition file, if you modified .dsc then require manual processing.
3.2.Create application , call network/host byte ordering functions
[code]
$ cat test_netorder.c
int test_netorder()
{
AllTypes st ;
int nret = 0 ;
/* client code */
memset( & st , 0x00 , sizeof(AllTypes) );
st.n1 = -0x11 ;
st.n2 = -0x1122 ;
st.n4 = -0x11223344 ;
#if ( defined __unix ) | ( defined __linux__ )
st.n8 = -0x1122334455667788LL ;
#elif ( defined _WIN32 )
st.n8 = -0x1122334455667788 ;
#endif
st.u1 = 0x11 ;
st.u2 = 0x1122 ;
st.u4 = 0x11223344 ;
#if ( defined __unix ) | ( defined __linux__ )
st.u8 = 0x1122334455667788ULL ;
#elif ( defined _WIN32 )
st.u8 = 0x1122334455667788 ;
#endif
st.f4 = 100.00 ;
st.f8 = 10000.00 ;
st.ch = 'A' ;
st.uch = 'B' ;
strcpy( st.str32 , "calvin" );
strcpy( st.str1024 , "XXXXXXXXXXXXXXXX" );
DSCLOG_AllTypes( & st );
nret = DSCNETORDER_AllTypes( & st ) ;
if( nret )
{
printf( "DSCNETORDER_AllTypes failed[%d]\n" , nret );
return nret;
}
else
{
printf( "DSCNETORDER_AllTypes ok\n" );
}
/* ... client send communication struct to server ... */
/* server code */
nret = DSCHOSTORDER_AllTypes( & st ) ;
if( nret )
{
printf( "DSCHOSTORDER_AllTypes failed[%d]\n" , nret );
return nret;
}
else
{
printf( "DSCHOSTORDER_AllTypes ok\n" );
}
DSCLOG_AllTypes( & st );
return 0;
}
$ make
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test_netorder.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c IDL_AllTypes.dsc.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -o test_netorder test_netorder.o IDL_AllTypes.dsc.o -L.
$ ./test_netorder
AllTypes.n1[-17]
AllTypes.n2[-4386]
AllTypes.n4[-287454020]
AllTypes.n8[-1234605616436508552]
AllTypes.u1[17]
AllTypes.u2[4386]
AllTypes.u4[287454020]
AllTypes.u8[1234605616436508552]
AllTypes.f4[100.000000]
AllTypes.f8[10000.000000]
AllTypes.ch[A]
AllTypes.uch[B]
AllTypes.str32[calvin]
AllTypes.str1024[XXXXXXXXXXXXXXXX]
DSCNETORDER_AllTypes ok
0x0000000000 ef 00 ee de ee dd cc bc ee dd cc bb aa 99 88 78 ...............x
0x0000000001 11 00 11 22 11 22 33 44 11 22 33 44 55 66 77 88 ..."."3D."3DUfw.
0x0000000002 00 00 c8 42 00 00 00 00 00 88 c3 40 41 42 63 61 ...B.......@ABca
0x0000000003 6c 76 69 6e 00 00 00 00 00 00 00 00 00 00 00 00 lvin............
0x0000000004 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 58 ...............X
0x0000000005 58 58 58 58 58 58 58 58 58 58 58 58 58 58 58 00 XXXXXXXXXXXXXXX.
...
DSCHOSTORDER_AllTypes ok
AllTypes.n1[-17]
AllTypes.n2[-4386]
AllTypes.n4[-287454020]
AllTypes.n8[-1234605616436508552]
AllTypes.u1[17]
AllTypes.u2[4386]
AllTypes.u4[287454020]
AllTypes.u8[1234605616436508552]
AllTypes.f4[100.000000]
AllTypes.f8[10000.000000]
AllTypes.ch[A]
AllTypes.uch[B]
AllTypes.str32[calvin]
AllTypes.str1024[XXXXXXXXXXXXXXXX]
[/code]
3.3.Create application , call serialize/deserilize functions
[code]
$ cat test_serialize_compact.c
int test_serialize_compact()
{
AllTypes st ;
char buf[ DSCSERIALIZE_COMPACT_BUFSIZE_AllTypes + 1 ] ;
int len ;
int nret = 0 ;
/* client code */
memset( & st , 0x00 , sizeof(AllTypes) );
st.n1 = -0x11 ;
st.n2 = -0x1122 ;
st.n4 = -0x11223344 ;
st.n8 = LL(-0x1122334455667788) ;
st.u1 = 0x11 ;
st.u2 = 0x1122 ;
st.u4 = 0x11223344 ;
st.u8 = ULL(0x1122334455667788) ;
st.f4 = 100.00 ;
st.f8 = 10000.00 ;
st.ch = 'A' ;
st.uch = 'B' ;
strcpy( st.str32 , "calvin" );
strcpy( st.str1024 , "XXXXXXXXXXXXXXXX" );
memset( buf , 0x00 , sizeof(buf) );
nret = DSCSERIALIZE_COMPACT_AllTypes( & st , buf , & len ) ;
if( nret )
{
printf( "DSCSERIALIZE_COMPACT_AllTypes failed[%d]\n" , nret );
return nret;
}
else
{
printf( "DSCSERIALIZE_COMPACT_AllTypes ok , len[%d]\n" , len );
}
dump( buf , len );
/* ... client send communication struct to server ... */
/* server code */
memset( & st , 0x00 , sizeof(AllTypes) );
nret = DSCDESERIALIZE_COMPACT_AllTypes( buf , & len , & st ) ;
if( nret )
{
printf( "DSCDESERIALIZE_COMPACT_AllTypes failed[%d]\n" , nret );
return nret;
}
else
{
printf( "DSCDESERIALIZE_COMPACT_AllTypes ok\n" );
}
DSCLOG_AllTypes( & st );
return 0;
}
$ make -f makefile.Linux
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test_netorder.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test_serialize_compact.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -o test_serialize_compact test_serialize_compact.o IDL_AllTypes.dsc.o -L.
$ ./test_serialize_compact
DSCSERIALIZE_COMPACT_AllTypes ok , len[1100]
0x0000000000 ef ee de ee dd cc bc ee dd cc bb aa 99 88 78 11 ..............x.
0x0000000001 11 22 11 22 33 44 11 22 33 44 55 66 77 88 00 00 ."."3D."3DUfw...
0x0000000002 c8 42 00 00 00 00 00 88 c3 40 41 42 63 61 6c 76 .B.......@ABcalv
0x0000000003 69 6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 in..............
0x0000000004 00 00 00 00 00 00 00 00 00 00 00 00 58 58 58 58 ............XXXX
0x0000000005 58 58 58 58 58 58 58 58 58 58 58 58 00 00 00 00 XXXXXXXXXXXX....
...
DSCDESERIALIZE_COMPACT_AllTypes ok
AllTypes.n1[-17]
AllTypes.n2[-4386]
AllTypes.n4[-287454020]
AllTypes.n8[-1234605616436508552]
AllTypes.u1[17]
AllTypes.u2[4386]
AllTypes.u4[287454020]
AllTypes.u8[1234605616436508552]
AllTypes.f4[100.000000]
AllTypes.f8[10000.000000]
AllTypes.ch[A]
AllTypes.uch[B]
AllTypes.str32[calvin]
AllTypes.str1024[XXXXXXXXXXXXXXXX]
[/code]
COMPACT serialization is to put all fields values in the memory image to a large data block, end-to-end, without filling space, and the integer value do byte order processing. Such as
STRUCT struct_name
{
INT 4 n4
STRING 256 str256
}
The layout of the serialized
n4(4bytes)+str256(256bytes)
total 260 bytes
Using serialization function with compressed make data block smaller.
$ cat test_serialize_compress.c
[code]
...
int test_serialize_compress()
{
AllTypes st ;
char buf[ DSCSERIALIZE_COMPRESS_BUFSIZE_AllTypes + 1 ] ;
int len ;
int nret = 0 ;
/* client code */
memset( & st , 0x00 , sizeof(AllTypes) );
st.n1 = -0x11 ;
st.n2 = -0x1122 ;
st.n4 = -0x11223344 ;
st.n8 = LL(-0x1122334455667788) ;
st.u1 = 0x11 ;
st.u2 = 0x1122 ;
st.u4 = 0x11223344 ;
st.u8 = ULL(0x1122334455667788) ;
st.f4 = 100.00 ;
st.f8 = 10000.00 ;
st.ch = 'A' ;
st.uch = 'B' ;
strcpy( st.str32 , "calvin" );
strcpy( st.str1024 , "XXXXXXXXXXXXXXXX" );
DSCLOG_AllTypes( & st );
memset( buf , 0x00 , sizeof(buf) );
nret = DSCSERIALIZE_COMPRESS_AllTypes( & st , buf , & len ) ;
if( nret )
{
printf( "DSCSERIALIZE_COMPRESS_AllTypes failed[%d]\n" , nret );
return nret;
}
else
{
printf( "DSCSERIALIZE_COMPRESS_AllTypes ok , len[%d]\n" , len );
}
dump( buf , len );
/* ... client send communication struct to server ... */
/* server code */
memset( & st , 0x00 , sizeof(AllTypes) );
nret = DSCDESERIALIZE_COMPRESS_AllTypes( buf , & len , & st ) ;
if( nret )
{
printf( "DSCDESERIALIZE_COMPRESS_AllTypes failed[%d]\n" , nret );
return nret;
}
else
{
printf( "DSCDESERIALIZE_COMPRESS_AllTypes ok\n" );
}
DSCLOG_AllTypes( & st );
return 0;
}
...
$ make -f makefile.Linux
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test_netorder.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test_serialize_compress.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -o test_serialize_compress test_serialize_compress.o IDL_AllTypes.dsc.o -L.
$ ./test_serialize_compress
AllTypes.n1[-17]
AllTypes.n2[-4386]
AllTypes.n4[-287454020]
AllTypes.n8[-1234605616436508552]
AllTypes.u1[17]
AllTypes.u2[4386]
AllTypes.u4[287454020]
AllTypes.u8[1234605616436508552]
AllTypes.f4[100.000000]
AllTypes.f8[10000.000000]
AllTypes.ch[A]
AllTypes.uch[B]
AllTypes.str32[calvin]
AllTypes.str1024[XXXXXXXXXXXXXXXX]
DSCSERIALIZE_COMPRESS_AllTypes ok , len[74]
0x0000000000 ef ee de 14 11 22 33 44 18 11 22 33 44 55 66 77 ....."3D.."3DUfw
0x0000000001 88 11 11 22 04 11 22 33 44 08 11 22 33 44 55 66 ...".."3D.."3DUf
0x0000000002 77 88 00 00 c8 42 00 00 00 00 00 88 c3 40 41 42 w....B.......@AB
0x0000000003 01 06 63 61 6c 76 69 6e 01 10 58 58 58 58 58 58 ..calvin..XXXXXX
0x0000000004 58 58 58 58 58 58 58 58 58 58 XXXXXXXXXX
DSCDESERIALIZE_COMPRESS_AllTypes ok
AllTypes.n1[-17]
AllTypes.n2[-4386]
AllTypes.n4[-287454020]
AllTypes.n8[-1234605616436508552]
AllTypes.u1[17]
AllTypes.u2[4386]
AllTypes.u4[287454020]
AllTypes.u8[1234605616436508552]
AllTypes.f4[100.000000]
AllTypes.f8[10000.000000]
AllTypes.ch[A]
AllTypes.uch[B]
AllTypes.str32[calvin]
AllTypes.str1024[XXXXXXXXXXXXXXXX]
[/code]
This case with compression , data block is 74 bytes , without compression is 1100 bytes.
The internal principle of COMPRESS serialization is on the basis of the compact serialization , and certain types of fields do compression transformation processing.
INT 4 types placed front header byte, left four bits, at present only is negative sign (positive for 0, negative for 1), four right bits for actual storage length, such as a value of network byte order is 0x00120034, actual storage of 0x1234, plus the front head, a total of 3 bytes
0x02 0x12 0x34
Value -0x1234 is also expressed in 3 bytes
0x12 0x12 0x34
INT 8 similar INT 4
UINT similar INT
STRING n type placed front UINT 4 field record , Such as "ABC", the actual length is 3 bytes, front UINT 4 fields 0x01 0x03, expressed in 5 bytes in total
0x01 0x03 0x61 0x62 0x63
Other field type without compression
For example
STRUCT struct_name
{
INT 4 n4
STRING 256 str256
}
for
n4=0x3456
str256="abc"
Compression serialized data
0x02 0x34 0x56 0x01 0x05 0x61 0x62 0x63
Total 8 bytes, is much shorter than compact serialization? this can save more traffic in the communication data exchange.
4.DirectStruct struct definition syntax
Each structure or embedded substructure definition format
[code]
STRUCT struct_name ARRAY struct_count
{
...
}
[/code]
after the first line ARRAY and is optional
Each field definition line format
[code]
field_type field_length field_name DEFAULT default_value
[/code]
field type and length supported
INT 1,2,4,8 ( 8 to 64 bits integer )
UINT 1,2,4,8
FLOAT 4,8
CHAR 1
UCHAR 1
STRING (N)
After DEFAULT is optional
Any line position can use references other .dsc file by
[code]
INCLUDE file_name
[/code]
Below is an example of a comprehensive
[code]
$ cat IDL_BankTransaction.dsc
STRUCT BankTransaction
{
INT 1 version DEFAULT 1
INCLUDE IDL_ResponseHeader.dsc
STRUCT QueryTransactionDetails
{
STRUCT AddonMessages ARRAY 3
{
STRING 64 message_text
}
STRUCT TransactionDetailTitle
{
STRING 64 title_text
INT 2 page_no
INT 2 page_size
}
STRUCT TransactionDetails ARRAY 10
{
STRING 10 trans_date
STRING 10 trans_time
STRING 6 outlet_id
STRING 20 card_no
FLOAT 4 trans_amount
}
}
}
$ cat IDL_ResponseHeader.dsc
STRUCT ResponseHeader
{
STRING 32 transaction_code
INT 4 trans_jnlsno
INT 4 response_code DEFAULT 0
STRING 1024 response_desc DEFAULT "OK"
}
[/code]
5.Performance
In high-performance situations, data serialization and deserialization efficiency is critical, mainly inspects the final message size and speed of serialization.
At the same time, we also took Google's Protocol Buffer to do comparative.
Pressure environment :
CPU : Intel(R) Core(TM) i3-3240 CPU 3.4GHz/3.4GHz
Memory : 2GB
OS : WINDOWS XP SP3 ( VMWare 6.0.1 ( Red Hat Enterprise Linux Server release 5.4 ) )
Pressure version :
DirectStruct-1.0.3.tar.gz
protobuf-2.3.0.tar.gz
Pressure structure :
DirectStruct
[code]
$ cat IDL_AllTypes2.dsc
STRUCT AllTypes2
{
INT 4 n4
INT 8 n8
UINT 4 u4
UINT 8 u8
FLOAT 4 f4
FLOAT 8 f8
STRING 32 str32
STRING 1024 str1024
}
$ dsc -f IDL_AllTypes2.dsc -c
$ ls
IDL_AllTypes2.dsc.c IDL_AllTypes2.dsc.h
[/code]
Google Protocol Buffer
[code]
$ cat PressProtobuf.proto
message PressProtobuf
{
required sint32 n4 = 2 ;
required sint64 n8 =3 ;
required int32 un4 = 5 ;
required int64 un8 = 6 ;
required float f4 = 7 ;
required double f8 = 8 ;
required string str32 = 9 ;
required string str1024 = 10 ;
}
$ protoc -I=. --cpp_out=. PressProtobuf.proto
$ ls
PressProtobuf.pb.cc PressProtobuf.pb.h
[/code]
Pressure code :
DirectStruct
[code]
$ cat test/test_serialize_compress_press.c
...
int test_serialize_compress_press( long count )
{
AllTypes2 st ;
char buf[ DSCSERIALIZE_COMPRESS_BUFSIZE_AllTypes2 + 1 ] ;
int len ;
long c ;
long t1 , t2 , dt ;
int nret = 0 ;
memset( & st , 0x00 , sizeof(AllTypes2) );
st.n4 = -0x11223344 ;
st.n8 = LL(-0x1122334455667788) ;
st.u4 = 0x11223344 ;
st.u8 = ULL(0x1122334455667788) ;
st.f4 = 100.00 ;
st.f8 = 10000.00 ;
strcpy( st.str32 , "calvin" );
strcpy( st.str1024 , "XXXXXXXXXXXXXXXX" );
DSCLOG_AllTypes2( & st );
printf( "Press begin\n" );
time( & t1 );
for( c = 0 ; c < count ; c++ )
{
memset( buf , 0x00 , sizeof(buf) );
nret = DSCSERIALIZE_COMPRESS_AllTypes2( & st , buf , & len ) ;
if( nret )
{
printf( "DSCSERIALIZE_COMPRESS_AllTypes2 failed[%d]\n" , nret );
return nret;
}
memset( & st , 0x00 , sizeof(AllTypes2) );
nret = DSCDESERIALIZE_COMPRESS_AllTypes2( buf , & len , & st ) ;
if( nret )
{
printf( "DSCDESERIALIZE_COMPRESS_AllTypes2 failed[%d]\n" , nret );
return nret;
}
}
printf( "Press end\n" );
time( & t2 );
dt = t2 - t1 ;
printf( "data compress size[%d] - compact size[%d]\n" , len , DSCSERIALIZE_COMPACT_BUFSIZE_AllTypes2 );
printf( "Elapse %ld seconds\n" , dt );
dump( buf , len );
DSCLOG_AllTypes2( & st );
return 0;
}
...
$ make -f makefile
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c IDL_AllTypes2.dsc.c
gcc -g -fPIC -O2 -Wall -Werror -fno-strict-aliasing -I. -c test_serialize_compress_press.c
gcc -o test_serialize_compress_press test_serialize_compress_press.o IDL_AllTypes2.dsc.o -L.
[/code]
Google Protocol Buffer
[code]
$ cat test_protobuf/test_protobuf_press.cc
...
int test_protobuf_press( int count )
{
PressProtobuf press ;
PressProtobuf press2 ;
string str ;
int len ;
int c ;
press.set_n4( -0x11223344 );
press.set_n8( -0x1122334455667788LL );
press.set_un4( 0x11223344 );
press.set_un8( 0x1122334455667788LL );
press.set_f4( 100.00 );
press.set_f8( 10000.00 );
press.set_str32( "calvin" );
press.set_str1024( "XXXXXXXXXXXXXXXX" );
printf( "[%d]\n" , press.n4() );
printf( "[%lld]\n" , press.n8() );
printf( "[%d]\n" , press.un4() );
printf( "[%lld]\n" , press.un8() );
printf( "[%f]\n" , press.f4() );
printf( "[%lf]\n" , press.f8() );
printf( "[%s]\n" , press.str32().c_str() );
printf( "[%s]\n" , press.str1024().c_str() );
for( c = 0 ; c < count ; c++ )
{
str = press.SerializeAsString() ;
press2.ParseFromString( str );
}
len = str.length() ;
printf( "[%d]\n" , len );
dump( (char*)str.c_str() , len );
printf( "[%d]\n" , press2.n4() );
printf( "[%lld]\n" , press2.n8() );
printf( "[%d]\n" , press2.un4() );
printf( "[%lld]\n" , press2.un8() );
printf( "[%f]\n" , press2.f4() );
printf( "[%lf]\n" , press2.f8() );
printf( "[%s]\n" , press2.str32().c_str() );
printf( "[%s]\n" , press2.str1024().c_str() );
return 0;
}
...
make
g++ -I. -c test_protobuf_press.cc
g++ -o test_protobuf_press test_protobuf_press.o PressProtobuf.pb.cc -L/usr/local/lib -lprotobuf -lpthread
[/code]
Pressure output :
DirectStruct
[code]
time ./test_serialize_compress_press 10000000
AllTypes2.n4[-287454020]
AllTypes2.n8[-1234605616436508552]
AllTypes2.u4[287454020]
AllTypes2.u8[1234605616436508552]
AllTypes2.f4[100.000000]
AllTypes2.f8[10000.000000]
AllTypes2.str32[calvin]
AllTypes2.str1024[XXXXXXXXXXXXXXXX]
Press begin
Press end
data compress size[66] - compact size[1092]
Elapse 1 seconds
0x0000000000 04 11 22 33 44 08 11 22 33 44 55 66 77 88 04 11 .."3D.."3DUfw...
0x0000000001 22 33 44 08 11 22 33 44 55 66 77 88 00 00 c8 42 "3D.."3DUfw....B
0x0000000002 00 00 00 00 00 88 c3 40 01 06 63 61 6c 76 69 6e .......@..calvin
0x0000000003 01 10 58 58 58 58 58 58 58 58 58 58 58 58 58 58 ..XXXXXXXXXXXXXX
0x0000000004 58 58 XX
AllTypes2.n4[-287454020]
AllTypes2.n8[-1234605616436508552]
AllTypes2.u4[287454020]
AllTypes2.u8[1234605616436508552]
AllTypes2.f4[100.000000]
AllTypes2.f8[10000.000000]
AllTypes2.str32[calvin]
AllTypes2.str1024[XXXXXXXXXXXXXXXX]
real 0m1.080s
user 0m1.074s
sys 0m0.007s
[/code]
Google Protocol Buffer
[code]
$ time ./test_protobuf_press 10000000
[-287454020]
[-1234605616436508552]
[287454020]
[1234605616436508552]
[100.000000]
[10000.000000]
[calvin]
[XXXXXXXXXXXXXXXX]
[72]
0x0000000000 10 87 cd 91 92 02 18 8f de b3 d6 8a d1 99 a2 22 ..............."
0x0000000001 28 c4 e6 88 89 01 30 88 ef 99 ab c5 e8 8c 91 11 (.....0.........
0x0000000002 3d 00 00 c8 42 41 00 00 00 00 00 88 c3 40 4a 06 =...BA.......@J.
0x0000000003 63 61 6c 76 69 6e 52 10 58 58 58 58 58 58 58 58 calvinR.XXXXXXXX
0x0000000004 58 58 58 58 58 58 58 58 XXXXXXXX
[-287454020]
[-1234605616436508552]
[287454020]
[1234605616436508552]
[100.000000]
[10000.000000]
[calvin]
[XXXXXXXXXXXXXXXX]
real 0m4.248s
user 0m4.235s
sys 0m0.011s
[/code]
Pressure conclusion :
* DirectStruct serialization(with compression) packet size is 66 bytes, while Google Protocol Buffer is 72 bytes, DirectStruct narrowly on serialization packet size.
* DirectStruct serialization/deserialization(with compression) again and again 10 million times costs 1.080s, while Google Protocol Buffer takes 4.248s, DirectStruct victory on serialization/deserialization performance.
* DirectStruct compilation client application code does not need additional header files and library files, only need IDL_AllTypes2.dsc.c,IDL_AllTypes2.dsc.h what generated by tool 'dsc' , while Google Protocol Buffer needs not only PressProtobuf.pb.cc,PressProtobuf.pb.h , also need a big pile head in /usr/local/include/Google/protobuf under and lib file /usr/local/lib/libprotobuf.a(9MB), also depends on the -lpthread, compile environment is complicated.
6.Finally
Welcome to use DirectStruct, if you have any problems or have a cool idea about DirectStruct, please tell me, thank you ^_^
Project home page : [url]https://github.com/calvinwilliams/DirectStruct[/url]
Author email : calvinwilliams.c@gmail.com
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/flw7887/DirectStruct.git
git@gitee.com:flw7887/DirectStruct.git
flw7887
DirectStruct
DirectStruct
master

搜索帮助