diff --git a/src/struct_pack/benchmark/benchmark.cpp b/src/struct_pack/benchmark/benchmark.cpp index 4749552ab..b38565014 100644 --- a/src/struct_pack/benchmark/benchmark.cpp +++ b/src/struct_pack/benchmark/benchmark.cpp @@ -26,6 +26,7 @@ using namespace std::string_literals; template 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()) { @@ -33,40 +34,49 @@ void calculate_ser_rate(const T& map, LibType base_line_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"; @@ -74,12 +84,30 @@ void calculate_ser_rate(const T& map, LibType base_line_type, template 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); +#if __cplusplus >= 202002L + calculate_ser_rate(map, base_line_type, SampleType::ZC_RECTS, + SampleType::RECTS); +#endif + 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); +#if __cplusplus >= 202002L + calculate_ser_rate(map, base_line_type, SampleType::ZC_MONSTERS, + SampleType::MONSTERS); +#endif } int main(int argc, char** argv) { diff --git a/src/struct_pack/benchmark/config.hpp b/src/struct_pack/benchmark/config.hpp index 135570867..1d40a8680 100644 --- a/src/struct_pack/benchmark/config.hpp +++ b/src/struct_pack/benchmark/config.hpp @@ -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 g_sample_name_map = { @@ -32,11 +35,16 @@ inline const std::unordered_map 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 g_lib_name_map = { {LibType::STRUCT_PACK, "struct_pack"}, diff --git a/src/struct_pack/benchmark/data_def.hpp b/src/struct_pack/benchmark/data_def.hpp index 677337547..7c820d46a 100644 --- a/src/struct_pack/benchmark/data_def.hpp +++ b/src/struct_pack/benchmark/data_def.hpp @@ -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 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 @@ -134,3 +144,35 @@ struct Monster { equipped, path); #endif }; +#if __cplusplus >= 202002L +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 weapons; + zc_Weapon equipped; + std::span 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; + }; +}; +#endif \ No newline at end of file diff --git a/src/struct_pack/benchmark/flatbuffer_sample.hpp b/src/struct_pack/benchmark/flatbuffer_sample.hpp index 796023576..d4a476145 100644 --- a/src/struct_pack/benchmark/flatbuffer_sample.hpp +++ b/src/struct_pack/benchmark/flatbuffer_sample.hpp @@ -55,7 +55,7 @@ inline void create(flatbuffers::FlatBufferBuilder &builder, static std::vector> 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); } diff --git a/src/struct_pack/benchmark/protobuf_sample.hpp b/src/struct_pack/benchmark/protobuf_sample.hpp index bdeaeeed8..7c74c8b1a 100644 --- a/src/struct_pack/benchmark/protobuf_sample.hpp +++ b/src/struct_pack/benchmark/protobuf_sample.hpp @@ -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); } diff --git a/src/struct_pack/benchmark/struct_pack_sample.hpp b/src/struct_pack/benchmark/struct_pack_sample.hpp index abaa05cab..a34bdb2c4 100644 --- a/src/struct_pack/benchmark/struct_pack_sample.hpp +++ b/src/struct_pack/benchmark/struct_pack_sample.hpp @@ -30,7 +30,7 @@ inline auto create_rect2s(size_t object_count) { inline auto create_persons(size_t object_count) { std::vector 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); } @@ -102,10 +102,20 @@ struct struct_pack_sample : public base_sample { deserialize(SampleType::RECTS, rects_); deserialize(SampleType::VAR_RECT, rect2s_[0]); deserialize(SampleType::VAR_RECTS, rect2s_); +#if __cplusplus >= 202002L + auto sp = std::span{rects_}; + deserialize(SampleType::ZC_RECTS, sp); +#endif deserialize(SampleType::PERSON, persons_[0]); deserialize(SampleType::PERSONS, persons_); + deserialize, std::vector>( + SampleType::ZC_PERSONS, persons_); deserialize(SampleType::MONSTER, monsters_[0]); deserialize(SampleType::MONSTERS, monsters_); +#if __cplusplus >= 202002L + deserialize, std::vector>( + SampleType::ZC_MONSTERS, monsters_); +#endif } private: @@ -131,13 +141,13 @@ struct struct_pack_sample : public base_sample { } buf_size_map_.emplace(sample_type, buffer_.size()); } - template + template void deserialize(SampleType sample_type, T &sample) { // get serialized buffer of sample for deserialize buffer_.clear(); struct_pack::serialize_to(buffer_, sample); - std::vector vec; + std::vector vec; vec.resize(ITERATIONS); uint64_t ns = 0; diff --git a/src/struct_pack/benchmark/struct_pb_sample.hpp b/src/struct_pack/benchmark/struct_pb_sample.hpp index 71621e732..b58bbbab7 100644 --- a/src/struct_pack/benchmark/struct_pb_sample.hpp +++ b/src/struct_pack/benchmark/struct_pb_sample.hpp @@ -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;