Serialization Implementation Method Based on Generic Programming

Hello World

#include <iostream>
int main(int argc, char* argv[])
{
std::cout << "Hello World!" << std::endl;
return 0;
}
namespace std
{
typedef basic_ostream<char> ostream;
}

Starting with the Standard Input and Output of C++

class MyClip 
{
bool mValid;
int mIn;
int mOut;
std::string mFilePath;
};
MyClip clip;
std::cout << clip;
inline std::istream& operator>>(std::istream& st, MyClip& clip)
{
st >> clip.mValid;
st >> clip.mIn >> clip.mOut;
st >> clip.mFilePath;
return st;
}
inline std::ostream& operator<<(std::ostream& st, MyClip const& clip)
{
st << clip.mValid << ' ';
st << clip.mIn << ' ' << clip.mOut << ' ';
st << clip.mFilePath << ' ';
return st;
}
friend std::istream& operator>>(std::istream& st, MyClip& clip);
friend std::ostream& operator<<(std::ostream& st, MyClip const& clip);
class MyVideo : public MyClip
{
std::list<MyFilter> mFilters;
};

Boost Serialization Library

template<typename Archive> friend void serialize(Archive&, MyClip&, unsigned int const);
template<typename A>void serialize(A &ar, MyClip &clip, unsigned int const ver) 
{
ar & BOOST_SERIALIZATION_NVP(clip.mValid);
ar & BOOST_SERIALIZATION_NVP(clip.mIn);
ar & BOOST_SERIALIZATION_NVP(clip.mOut);
ar & BOOST_SERIALIZATION_NVP(clip.mFilePath);
}
// store
MyClip clip;
...
std::ostringstream ostr;
boost::archive::text_oarchive oa(ostr);
oa << clip;
// load
std::istringstream istr(ostr.str());
boost::archive::text_iarchive ia(istr);
ia >> clip;
  • Compilation data on the terminal is little, and official data for the compilation on the terminal is basically not exist. When switching between different versions for compilation, various strange compilation errors are often encountered.
  • Boost is not compatible enough between different C++ development standards. In particular, many problems occur when the libc++ standard is used for compiling links.
  • Boost increases the size of the release package on the terminal
  • Boost adds private header information, such as serialization library and version number, to each serialization, and parses it again during deserialization, which reduces the performance in some scenarios.

Serialization Implementation Method Based on Generic Programming

  • The Boost serialization library is heavily used in existing projects, so compatibility with the existing code and the habits of developers is the primary goal.
  • The workload of code modification and refactoring is minimized.
  • It is compatible with different C++ development standards.
  • It provides higher performance than the Boost serialization library.
  • The size of the release package on the terminal is reduced.
#define BOOST_SERIALIZATION_NVP(value)  value
alivc::text_oarchive oa(ostr);
alivc::text_iarchive ia(istr);
explicit text_oarchive(std::ostream& ost, unsigned int version = 0);
template <typename T> text_oarchive& operator<<(T& v);
template <typename T> text_oarchive& operator&(T& v);
template <typename T>
text_oarchive& operator<<(T& v)
{
serialize(*this, v, mversion);
return *this;
}
template <typename T>
text_oarchive& operator&(T& v)
{
basic_save<T>::invoke(*this, v, mversion);
return *this;
}
template <typename T, bool E = false>
struct basic_load_save
{
template <typename A>
static void invoke(A& ar, T& v, unsigned int version)
{
serialize(ar, v, version);
}
};
template <typename T>
struct basic_save : public basic_load_save<T, std::is_enum<T>::value>
{
};
template <typename T>
struct basic_load_save<T, true>
{
template <typename A>
static void invoke(A& ar, T& v, unsigned int version)
{
int tmp = v;
ar & tmp;
v = (T)tmp;
}
};
template <typename T>
struct basic_pod_save
{
template <typename A>
static void invoke(A& ar, T const& v, unsigned int)
{
ar.template save(v);
}
};
template <>
struct basic_save<int> : public basic_pod_save<int>
{
};
template <typename T>
void save(T const& v)
{
most << v << ' ';
}

Test Results

  • The refactoring workload of code modification is very small. It is only necessary to delete the related header files of Boost, and replace the Boost related namespaces with the macros of alivc, BOOST_SERIALIZATION_FUNCTION, and BOOST_SERIALIZATION_NVP.
  • The size of the release package on Android is reduced by about 500 KB.
  • In the current message processing framework, the average time to process a message is reduced from 100 us to 25 us.
  • The code implementation is about 300 lines, which is more lightweight.

Future Work

Conclusion

  • Generic programming can greatly improve development efficiency, especially in code reusability. At the same time, its type derivation and code generation are completed at compile time, so it does not reduce the performance.
  • Serialization plays an important role in the decoupling process that requires dumping-recovering and in assisting in the cause analysis of exceptions and crashes.
  • By using the language features of C++ and the template itself, and combining with reasonable architecture design, it is easy to expand and avoid excessive design.

References

--

--

--

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How to Synchronize RDS Data to a Local User-Defined Database

鬼灭之刃剧场版:无限列车篇 完整版本 [Demon Slayer: Kimetsu no Yaiba] 完整版觀看電影在線小鴨 (2020-HD)完整的電影

Levels of Abstraction

Take back your Facebook & Instagram posts

How does web browsers work?

A simple Use Case of Docker

Python vs NodeJs: Which one should you go for in 2022?

In Defence of Exceptions

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alibaba Cloud

Alibaba Cloud

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com

More from Medium

Apache Kafka Exam Notes

Creating DAG in Apache Airflow

Managing Data in Containers

Cache data with Redis in CakePHP 4