Skip to content

Commit

Permalink
[struct_pack] add benchmark for zero-copy & varint
Browse files Browse the repository at this point in the history
  • Loading branch information
poor-circle committed Dec 12, 2023
1 parent 13a24b8 commit 033a23e
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 47 deletions.
92 changes: 57 additions & 35 deletions src/struct_pack/benchmark/benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,60 +26,82 @@
using namespace std::string_literals;
template <typename T>
void calculate_ser_rate(const T& map, LibType base_line_type,
SampleType base_line_sample_type,
SampleType sample_type) {
auto it = map.find(base_line_type);
if (it == map.end()) {
throw std::invalid_argument("unknown lib type");
}

auto base_lib = it->second;
auto base_line_ser = base_lib->get_ser_time_elapsed_map()[sample_type];
auto base_line_deser = base_lib->get_deser_time_elapsed_map()[sample_type];
auto base_line_ser =
base_lib->get_ser_time_elapsed_map()[base_line_sample_type];
auto base_line_deser =
base_lib->get_deser_time_elapsed_map()[base_line_sample_type];

for (auto [lib_type, other_lib] : map) {
if (lib_type == base_line_type) {
continue;
}

auto ns_ser = other_lib->get_ser_time_elapsed_map()[sample_type];
auto ns_deser = other_lib->get_deser_time_elapsed_map()[sample_type];
double rate_ser = std::ceil(double(ns_ser) / base_line_ser * 100.0) / 100.0;
double rate_deser =
std::ceil(double(ns_deser) / base_line_deser * 100.0) / 100.0;

std::string prefix_ser = base_lib->name()
.append(" serialize ")
.append(get_sample_name(sample_type))
.append(" is ");
std::string prefix_deser = base_lib->name()
.append(" deserialize ")
.append(get_sample_name(sample_type))
.append(" is ");

auto space_ser = get_space_str(prefix_ser.size(), 39);
auto space_deser = get_space_str(prefix_deser.size(), 39);

std::cout << prefix_ser << space_ser << "[" << rate_ser
<< "] times faster than " << other_lib->name() << ", ["
<< base_line_ser << ", " << ns_ser << "]"
<< "\n";
std::cout << prefix_deser << space_deser << "[" << rate_deser
<< "] times faster than " << other_lib->name() << ", ["
<< base_line_deser << ", " << ns_deser << "]"
<< "\n";
if (base_line_ser != 0) {
auto ns_ser = other_lib->get_ser_time_elapsed_map()[sample_type];
double rate_ser =
std::ceil(double(ns_ser) / base_line_ser * 100.0) / 100.0;

std::string prefix_ser =
base_lib->name()
.append(" serialize ")
.append(get_sample_name(base_line_sample_type))
.append(" is ");

auto space_ser = get_space_str(prefix_ser.size(), 39);

std::cout << prefix_ser << space_ser << "[" << rate_ser
<< "] times faster than " << other_lib->name() << ", ["
<< base_line_ser << ", " << ns_ser << "]"
<< "\n";
}
if (base_line_deser != 0) {
auto ns_deser = other_lib->get_deser_time_elapsed_map()[sample_type];
double rate_deser =
std::ceil(double(ns_deser) / base_line_deser * 100.0) / 100.0;
std::string prefix_deser =
base_lib->name()
.append(" deserialize ")
.append(get_sample_name(base_line_sample_type))
.append(" is ");

auto space_deser = get_space_str(prefix_deser.size(), 39);
std::cout << prefix_deser << space_deser << "[" << rate_deser
<< "] times faster than " << other_lib->name() << ", ["
<< base_line_deser << ", " << ns_deser << "]"
<< "\n";
}
}

std::cout << "========================\n";
}
template <typename T>
void run_benchmark(const T& map, LibType base_line_type) {
std::cout << "======== calculate serialization rate ========\n";
calculate_ser_rate(map, base_line_type, SampleType::RECT);
calculate_ser_rate(map, base_line_type, SampleType::RECTS);
calculate_ser_rate(map, base_line_type, SampleType::PERSON);
calculate_ser_rate(map, base_line_type, SampleType::PERSONS);
calculate_ser_rate(map, base_line_type, SampleType::MONSTER);
calculate_ser_rate(map, base_line_type, SampleType::MONSTERS);
calculate_ser_rate(map, base_line_type, SampleType::RECT, SampleType::RECT);
calculate_ser_rate(map, base_line_type, SampleType::VAR_RECT,
SampleType::RECT);
calculate_ser_rate(map, base_line_type, SampleType::RECTS, SampleType::RECTS);
calculate_ser_rate(map, base_line_type, SampleType::VAR_RECTS,
SampleType::RECTS);
calculate_ser_rate(map, base_line_type, SampleType::PERSON,
SampleType::PERSON);
calculate_ser_rate(map, base_line_type, SampleType::PERSONS,
SampleType::PERSONS);
calculate_ser_rate(map, base_line_type, SampleType::ZC_PERSONS,
SampleType::PERSONS);
calculate_ser_rate(map, base_line_type, SampleType::MONSTER,
SampleType::MONSTER);
calculate_ser_rate(map, base_line_type, SampleType::MONSTERS,
SampleType::MONSTERS);
calculate_ser_rate(map, base_line_type, SampleType::ZC_MONSTERS,
SampleType::MONSTERS);
}

int main(int argc, char** argv) {
Expand Down
12 changes: 10 additions & 2 deletions src/struct_pack/benchmark/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ enum class LibType {
enum class SampleType {
RECT,
RECTS,
ZC_RECTS,
VAR_RECT,
VAR_RECTS,
PERSON,
PERSONS,
ZC_PERSONS,
MONSTER,
MONSTERS
MONSTERS,
ZC_MONSTERS,
};

inline const std::unordered_map<SampleType, std::string> g_sample_name_map = {
Expand All @@ -32,11 +35,16 @@ inline const std::unordered_map<SampleType, std::string> g_sample_name_map = {
{SampleType::VAR_RECT, "1 rect(with fast varint edcode)"},
{SampleType::VAR_RECTS,
std::to_string(OBJECT_COUNT) + " rects(with fast varint edcode)"},
{SampleType::ZC_RECTS,
std::to_string(OBJECT_COUNT) + " rects(with zero-copy deserialize)"},
{SampleType::PERSON, "1 person"},
{SampleType::PERSONS, std::to_string(OBJECT_COUNT) + " persons"},
{SampleType::ZC_PERSONS,
std::to_string(OBJECT_COUNT) + " persons(with zero-copy deserialize)"},
{SampleType::MONSTER, "1 monster"},
{SampleType::MONSTERS, std::to_string(OBJECT_COUNT) + " monsters"},
};
{SampleType::ZC_MONSTERS,
std::to_string(OBJECT_COUNT) + " monsters(with zero-copy deserialize)"}};

inline const std::unordered_map<LibType, std::string> g_lib_name_map = {
{LibType::STRUCT_PACK, "struct_pack"},
Expand Down
49 changes: 45 additions & 4 deletions src/struct_pack/benchmark/data_def.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,22 @@ struct person {
#endif
};

struct zc_person {
int32_t id;
std::string_view name;
int age;
double salary;
#ifdef HAVE_MSGPACK
MSGPACK_DEFINE(id, name, age, salary);
#endif
};

template <typename T>
struct rect {
T x;
T y;
T width;
T height;
T x = 1;
T y = 0;
T width = 11;
T height = 1;
#ifdef HAVE_MSGPACK
MSGPACK_DEFINE(x, y, width, height);
#endif
Expand Down Expand Up @@ -134,3 +144,34 @@ struct Monster {
equipped, path);
#endif
};

struct zc_Weapon {
std::string_view name;
int16_t damage;

bool operator==(const zc_Weapon &rhs) const {
return name == rhs.name && damage == rhs.damage;
};
#ifdef HAVE_MSGPACK
MSGPACK_DEFINE(name, damage);
#endif
};

struct zc_Monster {
Vec3 pos;
int16_t mana;
int16_t hp;
std::string_view name;
std::string_view inventory;
Color color;
std::vector<zc_Weapon> weapons;
zc_Weapon equipped;
std::span<Vec3> path;

bool operator==(const zc_Monster &rhs) const {
return pos == rhs.pos && mana == rhs.mana && hp == rhs.hp &&
name == rhs.name && inventory == rhs.inventory &&
color == rhs.color && weapons == rhs.weapons &&
equipped == rhs.equipped;
};
};
2 changes: 1 addition & 1 deletion src/struct_pack/benchmark/flatbuffer_sample.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ inline void create<fb::persons>(flatbuffers::FlatBufferBuilder &builder,
static std::vector<flatbuffers::Offset<fb::person>> persons_vector;
persons_vector.clear();
for (int i = 0; i < object_count; i++) {
auto name = builder.CreateString("Sword");
auto name = builder.CreateString(std::string(1024, 'A'));
auto person = fb::Createperson(builder, 24, name, 432798, 65536.42);
persons_vector.emplace_back(person);
}
Expand Down
2 changes: 1 addition & 1 deletion src/struct_pack/benchmark/protobuf_sample.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ inline mygame::persons create_persons(size_t object_count) {
for (int i = 0; i < object_count; i++) {
auto *p = ps.add_person_list();
p->set_id(432798);
p->set_name("tom");
p->set_name(std::string(1024, 'A'));
p->set_age(24);
p->set_salary(65536.42);
}
Expand Down
12 changes: 9 additions & 3 deletions src/struct_pack/benchmark/struct_pack_sample.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ inline auto create_rect2s(size_t object_count) {

inline auto create_persons(size_t object_count) {
std::vector<person> v{};
person p{432798, "tom", 24, 65536.42};
person p{432798, std::string(1024, 'A'), 24, 65536.42};
for (std::size_t i = 0; i < object_count; i++) {
v.push_back(p);
}
Expand Down Expand Up @@ -102,10 +102,16 @@ struct struct_pack_sample : public base_sample {
deserialize(SampleType::RECTS, rects_);
deserialize(SampleType::VAR_RECT, rect2s_[0]);
deserialize(SampleType::VAR_RECTS, rect2s_);
auto sp = std::span{rects_};
deserialize(SampleType::ZC_RECTS, sp);
deserialize(SampleType::PERSON, persons_[0]);
deserialize(SampleType::PERSONS, persons_);
deserialize<std::vector<person>, std::vector<zc_person>>(
SampleType::ZC_PERSONS, persons_);
deserialize(SampleType::MONSTER, monsters_[0]);
deserialize(SampleType::MONSTERS, monsters_);
deserialize<std::vector<Monster>, std::vector<zc_Monster>>(
SampleType::ZC_MONSTERS, monsters_);
}

private:
Expand All @@ -131,13 +137,13 @@ struct struct_pack_sample : public base_sample {
}
buf_size_map_.emplace(sample_type, buffer_.size());
}
template <typename T>
template <typename T, typename U = T>
void deserialize(SampleType sample_type, T &sample) {
// get serialized buffer of sample for deserialize
buffer_.clear();
struct_pack::serialize_to(buffer_, sample);

std::vector<T> vec;
std::vector<U> vec;
vec.resize(ITERATIONS);

uint64_t ns = 0;
Expand Down
5 changes: 4 additions & 1 deletion src/struct_pack/benchmark/struct_pb_sample.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ inline auto create_rects(std::size_t object_count) {
inline auto create_persons(std::size_t object_count) {
persons ps;
for (int i = 0; i < object_count; ++i) {
person p{.id = 432798, .name = "tom", .age = 24, .salary = 65536.42};
person p{.id = 432798,
.name = std::string(1024, 'A'),
.age = 24,
.salary = 65536.42};
ps.person_list.emplace_back(p);
}
return ps;
Expand Down

0 comments on commit 033a23e

Please sign in to comment.