Мне сказали, что производительность flatbuffer лучше, чем proto, я проверил производительность на flatbuffer и protobuf, я могу быть уверен, что вектор std не оказал влияния больше чем прото. Protobuf лучше flatbuf или я ошибся в некоторых деталях?
образец плоского буфера
#include"person.pb.h"
#include<sys/time.h>
int main(int argc,char *argv[])
{
if(argc<2)
{
printf("<usage> num\n");
return -1;
}
size_t iNum = strtoul(argv[1],NULL,10);
person::School school;
for(size_t i=0;i<iNum;++i)
{
person::Person *p = school.add_student();
p->set_name("rockycai");
p->set_age(i);
}
timeval tbegin,tend;
std::string buffer;
gettimeofday(&tbegin,NULL);
school.SerializeToString(&buffer);
gettimeofday(&tend,NULL);
unsigned long int uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 +
(tend.tv_usec - tbegin.tv_usec) / 1000;
printf("serialize size %u cost time %lu\n",buffer.size(),uUsedMs);
person::School school1;
gettimeofday(&tbegin,NULL);
school1.ParseFromString(buffer);
gettimeofday(&tend,NULL);
uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 +
(tend.tv_usec - tbegin.tv_usec) / 1000;
printf("deserialize time %lu\n",uUsedMs);
return 0;
}
образец protbuf:
timeval tbegin,tend;
gettimeofday(&tbegin,NULL);
timeval tbegin1,tend1;
unsigned long int iTotal = 0;
for(size_t i=0;i<iNum;++i)
{
auto name = builder.CreateString("rockycai");
uint32_t age = i;
auto student = CreateStudent(builder,name,age);
gettimeofday(&tbegin1,NULL);
student_vector.push_back(student);
gettimeofday(&tend1,NULL);
iTotal += ((tend1.tv_sec - tbegin1.tv_sec) * 1000 + (tend1.tv_usec - tbegin1.tv_usec) / 1000);
}
gettimeofday(&tend,NULL);
unsigned long int uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 +
(tend.tv_usec - tbegin.tv_usec) / 1000;
printf("insert time %lu vector time %lu\n",uUsedMs,iTotal);
gettimeofday(&tbegin,NULL);
auto vecStu = builder.CreateVector(student_vector);
auto school = CreateSchool(builder,vecStu);
gettimeofday(&tend,NULL);
uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 + (tend.tv_usec - tbegin.tv_usec) / 1000;
printf("flat prepare time %lu\n",uUsedMs);
gettimeofday(&tbegin,NULL);
builder.Finish(school);
gettimeofday(&tend,NULL);
uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 +
(tend.tv_usec - tbegin.tv_usec) / 1000;
printf("serialized size %u costtime %lu\n",builder.GetSize(),uUsedMs);
gettimeofday(&tbegin,NULL);
auto res = GetSchool(builder.GetBufferPointer());
gettimeofday(&tend,NULL);
uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 + (tend.tv_usec - tbegin.tv_usec) / 1000;
printf("deserialize time %lu\n",uUsedMs);
результат плоского буфера
$ ./sample_person 10000000
insert time 9232 vector time 1
flat prepare time 1493
serialized size 320000024 costtime 0
deserialize time 0
Результат протокола
$ ./test_person 10000000
serialize size 167886336 cost time 2799
deserialize time 4446
плоское определение
namespace My.School;
table Student
{
name:string;
age:uint32;
}
table School
{
student:[Student];
}
root_type School;
прото определение
package person;
message Person
{
optional string name = 1;
optional uint32 age = 2;
}
message School
{
repeated Person student = 1;
}
обновить ... весь код:
#include "person_generated.h"
#include<sys/time.h>
using namespace My::School;
int main(int argc,char *argv[])
{
timeval ttbegin,ttend;
gettimeofday(&ttbegin,NULL);
if(argc<2)
{
printf("<usage> num\n");
return -1;
}
size_t iNum = strtoul(argv[1],NULL,10);
flatbuffers::FlatBufferBuilder builder(10000000);
std::vector<flatbuffers::Offset<Student>> student_vector;
student_vector.reserve(10000000);
timeval tbegin,tend;
gettimeofday(&tbegin,NULL);
//timeval tbegin1,tend1;
unsigned long int iTotal = 0;
for(size_t i=0;i<iNum;++i)
{
auto name = builder.CreateString("rockycai");
uint32_t age = i;
auto student = CreateStudent(builder,name,age);
//gettimeofday(&tbegin1,NULL);
student_vector.push_back(student);
//gettimeofday(&tend1,NULL);
//iTotal += ((tend1.tv_sec - tbegin1.tv_sec) * 1000 + (tend1.tv_usec - tbegin1.tv_usec) / 1000);
}
gettimeofday(&tend,NULL);
unsigned long int uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 +
(tend.tv_usec - tbegin.tv_usec) / 1000;
printf("insert time %lu\n",uUsedMs);
gettimeofday(&tbegin,NULL);
auto vecStu = builder.CreateVector(student_vector);
auto school = CreateSchool(builder,vecStu);
gettimeofday(&tend,NULL);
uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 + (tend.tv_usec - tbegin.tv_usec) / 1000;
printf("flat prepare time %lu\n",uUsedMs);
gettimeofday(&tbegin,NULL);
builder.Finish(school);
gettimeofday(&tend,NULL);
uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 +
(tend.tv_usec - tbegin.tv_usec) / 1000;
printf("serialized size %u costtime %lu\n",builder.GetSize(),uUsedMs);
gettimeofday(&tbegin,NULL);
auto res = GetSchool(builder.GetBufferPointer());
gettimeofday(&tend,NULL);
uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 + (tend.tv_usec - tbegin.tv_usec) / 1000;
printf("deserialize time %lu\n",uUsedMs);
gettimeofday(&ttend,NULL);
uUsedMs = (ttend.tv_sec - ttbegin.tv_sec) * 1000 + (ttend.tv_usec - ttbegin.tv_usec) / 1000;
printf("total time %lu\n",uUsedMs);
return 0;
}
#include"person.pb.h"
#include<sys/time.h>
int main(int argc,char *argv[])
{
timeval ttbegin,ttend;
gettimeofday(&ttbegin,NULL);
if(argc<2)
{
printf("<usage> num\n");
return -1;
}
size_t iNum = strtoul(argv[1],NULL,10);
person::School school;
timeval tbegin,tend;
gettimeofday(&tbegin,NULL);
for(size_t i=0;i<iNum;++i)
{
person::Person *p = school.add_student();
p->set_name("rockycai");
p->set_age(i);
}
gettimeofday(&tend,NULL);
unsigned long int uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 + (tend.tv_usec - tbegin.tv_usec) / 1000;
printf("vector time %lu\n",uUsedMs);
std::string buffer;
gettimeofday(&tbegin,NULL);
school.SerializeToString(&buffer);
gettimeofday(&tend,NULL);
uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 +
(tend.tv_usec - tbegin.tv_usec) / 1000;
printf("serialize size %u cost time %lu\n",buffer.size(),uUsedMs);
person::School school1;
gettimeofday(&tbegin,NULL);
school1.ParseFromString(buffer);
gettimeofday(&tend,NULL);
uUsedMs = (tend.tv_sec - tbegin.tv_sec) * 1000 +
(tend.tv_usec - tbegin.tv_usec) / 1000;
printf("deserialize time %lu\n",uUsedMs);
gettimeofday(&ttend,NULL);
uUsedMs = (ttend.tv_sec - ttbegin.tv_sec) * 1000 + (ttend.tv_usec - ttbegin.tv_usec) / 1000;
printf("total time %lu\n",uUsedMs);
return 0;
}
res is:
$ ./sample_person 10000000
insert time 7763
flat prepare time 1159
serialized size 320000024 costtime 0
deserialize time 0
total time 8922
$ ./test_person 10000000
vector time 2598
serialize size 167886336 cost time 2706
deserialize time 4676
total time 9981