使用Boost的Serialization库序列化STL标准容器
使用Boost做对象序列化是非常方便的,本文将介绍一种序列化STL标准容器的方法。
这是之前设计的异步框架的一个子功能:过程A将标准容器数据序列化成二进制流,然后将该二进制数据发送到过程B,过程B将数据反序列化为标准容器。(转载请指明出于breaksoftware的csdn博客)
下面这个基类支持vector、set、unordered set、multiset、unordered multiset、map、unordered map、multimap和unordered multimap。
/*************************************************************************> File Name: serialization.h> Author: fangliang> Mail: fangliang1988@gmail.com > Created Time: Fri 23 Mar 2018 03:11:14 PM CST************************************************************************/
#ifndef STLSERIALIZATION_SERIALIZATION_H
#define STLSERIALIZATION_SERIALIZATION_H#include <string>
#include <sstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp> namespace stl_serialization {template<class T>
class Serialization : public T {
public:void serialization(std::ostringstream& ostream) {boost::archive::binary_oarchive oa(ostream);oa << *this;}void unserialization(std::istringstream& istream) {boost::archive::binary_iarchive ia(istream);ia >> *this;}
private: friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int version) { ar & boost::serialization::base_object<T>(*this); }
};}#endif // STLSERIALIZATION_SERIALIZATION_H
可被序列化的标准容器只要继承该基类即可。以map为例
/*************************************************************************> File Name: map_serialization.h> Author: fangliang> Mail: fangliang1988@gmail.com > Created Time: Thu 22 Mar 2018 11:09:11 PM CST************************************************************************/
#ifndef STLSERIALIZATION_MAP_SERIALIZATION_H
#define STLSERIALIZATION_MAP_SERIALIZATION_H#include <map>
#include <string>
#include <sstream>
#include <boost/serialization/map.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>#include "serialization.h"namespace stl_serialization {template<class T, class T1>
class MapSerialization : public Serialization<std::map<T, T1> > {
};}#endif // STLSERIALIZATION_MAP_SERIALIZATION_H
使用一个单元测试来测试这段代码
/*************************************************************************> File Name: ut_map_serialization.cpp> Author: fangliang> Mail: fangliang1988@gmail.com > Created Time: Thu 22 Mar 2018 11:11:46 PM CST************************************************************************/
#include "gtest/gtest.h"
#include "./src/stl_serialization/map_serialization.h"using stl_serialization::MapSerialization;int main(int argc, char* argv[]) {testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}namespace unit_test {class UtMapSerialization :public ::testing::Test
{
protected:virtual void SetUp() {MapSerialization<int, std::string> ms_src;for (int i = 0; i < _size; i++) {ms_src[i] = " ";}ms_src.serialization(_ost);}virtual void TearDown() {}
protected:int _size = 10000;std::ostringstream _ost;
};TEST_F(UtMapSerialization, SizeEq) {MapSerialization<int, std::string> ms_des;std::istringstream ist(_ost.str());ms_des.unserialization(ist);ASSERT_EQ(_size, ms_des.size());
}TEST_F(UtMapSerialization, ElemEq) {MapSerialization<int, std::string> ms_des;std::istringstream ist(_ost.str());ms_des.unserialization(ist);int i = 0;for (std::map<int, std::string>::iterator it = ms_des.begin(); it != ms_des.end(); it++) {ASSERT_EQ(it->first, i++);}
}}
如果STL的容器中存放在的是一个非标准类型,比如一个用户自定义类型,则需要让该类型实现serialize方法。以vector为例
/*************************************************************************> File Name: vector_serialization.h> Author: fangliang> Mail: fangliang1988@gmail.com > Created Time: Thu 22 Mar 2018 03:41:16 PM CST************************************************************************/
#ifndef STLSERIALIZATION_VECTOR_SERIALIZATION_H
#define STLSERIALIZATION_VECTOR_SERIALIZATION_H#include <vector>
#include <string>
#include <sstream>
#include <boost/serialization/vector.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp> #include "serialization.h"namespace stl_serialization {template<class T>
class VectorSerialization : public Serialization<std::vector<T> > {
};}#endif // STLSERIALIZATION_VECTOR_SERIALIZATION_H
下面代码中,由于TestData是容器承载的类型,所以它需要增加24~33行代码用于容器内对象序列化。
/*************************************************************************> File Name: ut_vecotr_serialization.cpp> Author: fangliang> Mail: fangliang1988@gmail.com > Created Time: Wed 21 Mar 2018 02:34:18 PM CST************************************************************************/
#include "gtest/gtest.h"
#include "./src/stl_serialization/vector_serialization.h"using stl_serialization::VectorSerialization;int main(int argc, char* argv[]) {testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}namespace unit_test {struct TestData {int interger;double db;float fl;std::string str;
private: friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int version) { ar & interger;ar & db;ar & fl;ar & str;}
};class UtVectorSerialization :public ::testing::Test
{
protected:virtual void SetUp() {VectorSerialization<int> vs_src;for (int i = 0; i < _size; i++) {TestData item;item.interger = i;item.db = i;item.fl = i;item.str = std::to_string(i);vs_src.push_back(item);}vs_src.serialization(_ost);}virtual void TearDown() {}
protected:int _size = 10000;std::ostringstream _ost;
};TEST_F(UtVectorSerialization, SizeEq) {VectorSerialization<int> vs_des;std::istringstream ist(_ost.str());vs_des.unserialization(ist);ASSERT_EQ(_size, vs_des.size());
}TEST_F(UtVectorSerialization, ElemEq) {VectorSerialization<int> vs_des;std::istringstream ist(_ost.str());vs_des.unserialization(ist);for (int i = 0; i < _size; i++) {const TestData& item = vs_des.at(i);ASSERT_EQ(item.interger, i);ASSERT_DOUBLE_EQ(item.db, i);ASSERT_FLOAT_EQ(item.db, i);std::string str = std::to_string(i);ASSERT_STREQ(item.str.c_str(), str.c_str()); }
}}
最后我们看下包含10000个对象的容器反序列化耗时,总体来说效率还是不错的。
最后说下,unordered set、unordered multiset、unordered map和unordered multimap等不保证序列化前后容器中元素顺序一致。
相关文章:
连登GitHub TOP榜,中国开发者在行动!
作者 | 唐小引数据 | 于瑞洋出品 | AI科技大本营(ID:rgznai100)中国开发者正在走向世界中文开源项目正在不断登上 GitHub TOP 榜不久前,一个名叫「wuhan2020」的开源项目进入了 GitHub Trending TOP 榜,截至到现在,已经…

Merge into的使用
用途 merge 命令可以用来用一个表中的数据来修改或者插入到另一个表。插入或者修改的操作取决于on子句的条件。该语句可以在同一语句中执行两步操作,可以减少执行多条insert 和update语句。merge是一个确定性的语句,即不会在同一条merge语句中去对同一条…

PHP和MySQL Web开发从新手到高手,第8天-创建categories管理页面
1. 创建categories管理页面 主要包含以下几个页面: A. index.php, 准备各种变量数据.供展示页面使用. B. categories.html.php, 显示categories. C. form.html.php, 用于编缉或添加作者的页面. 页面郊果: 2. categories页面的主要流程 2.1 是否已登录 if (!user_is_login()){in…

堆状态分析的利器——valgrind的DHAT
在《堆问题分析的利器——valgrind的massif》一文中,我们介绍了如何使用massif查看和分析堆分配/释放的问题。但是除了申请和释放,堆空间还有其他问题,比如堆空间的使用率、使用周期等。通过分析这些问题,我们可以对程序代码进行优…

cisco2950交换机密码恢复
在实际工作中可能会忘记交换机密码,导致不能对交换机进行配置的情况。cisco提供了密码恢复的方法。以下是关于交换机密码恢复说明:如果忘记密码,这时我们如果要配置交换机就必须在启动时绕过config.text的配置【密码保存在config.text中】然后…
程序员SQL都不会?能干啥?资深研发:别再瞎努力了!
国外有人曾做过调查显示:“SQL的使用人数仅次于JavaScript”。更有统计,世界上一流的互联网公司中,排名前 20 的有 80% 都是 MySQL 的忠实用户。为什么这项技术仍有这么多人在用?又为什么值得我们学习?1、无论你是前端…

OC管理文件方法
1、常见的NSFileManager文件方法 -(NSData *)contentsAtPath:path //从一个文件读取数据 -(BOOL)createFileAtPath: path contents:(NSData *)data attributes:attr //向一个文件写入数据 -(BOOL)removeItemAtPath:path error:err //删除一个文件 -(BOOL)moveItemAtPa…
堆状态分析的利器——gperftools的Heap Profiler
在《内存泄漏分析的利器——gperftools的Heap Checker》一文中,我们介绍了如何使用gperftools分析内存泄漏。本文将介绍其另一个强大的工具——Heap Profiler去分析堆的变化过程。(转载请指明出于breaksoftware的csdn博客) 我们使用类似于《堆…

亲戚称呼关系表
直系血亲父系曾曾祖父--曾祖父--祖父--父亲曾曾祖母--曾祖母--祖母--父亲母系曾曾外祖父--曾外祖父--外祖父--母亲曾曾外祖母--曾外祖母--外祖母--母亲儿子:夫妻间男性的第一子代。女儿:夫妻间女性的第一子代。孙:夫妻间的第二子代࿰…
技术驰援抗疫一线, Python 线上峰会免费学!
截至截止2月9号24时,新型冠状病毒在全国已确诊42714例,疑似病例已达21675例。而专家所说的“拐点”始终未至,受疫的影响,各大公司开启远程办公模式,将返回工作场所办公的时间一延再延。在抗疫前线,中国医疗…

ZeroMq实现跨线程通信
ZeroMq实现跨线程通信 之前在技术崇拜的技术经理指导下阅读了ZeroMq的基础代码,现在就将阅读的心得与成果记录一下,并重新模仿实现了一下经理的异步队列。 1、对外接口 //主要接口(1)void *ymq_attach (void *ctx_, int oid, voi…
动态执行流程分析和性能瓶颈分析的利器——gperftools的Cpu Profiler
在《动态执行流程分析和性能瓶颈分析的利器——valgrind的callgrind》中,我们领略了valgrind对流程和性能瓶颈分析的强大能力。本文将介绍拥有相似能力的gperftools的Cpu Profiler。(转载请指明出于breaksoftware的csdn博客) 我们依然以callg…

C语言内存管理内幕(二)----半自动内存管理策略
2019独角兽企业重金招聘Python工程师标准>>> C语言内存管理内幕(二)----半自动内存管理策略 转载于:https://my.oschina.net/hengcai001/blog/466
无人机巡逻喊话、疫情排查、送药消毒,抗疫战中机器人化身钢铁战士!
整理 | 夕颜责编 | Carol出品 | CSDN(ID:CSDNnews)这场抗疫战争似乎格外漫长,但回头细数一下才发现,自疫情爆发以来,也不过半月之久。在接下来的几个半月中,抗疫战仍将继续,各方力量也要绷紧神经…

jQuery EasyUI 表单插件 - Datebox 日期框
为什么80%的码农都做不了架构师?>>> 扩展自 $.fn.combo.defaults。通过 $.fn.datebox.defaults 重写默认的 defaults。 日期框(datebox)把可编辑的文本框和下拉日历面板结合起来,用户可以从下拉日历面板中选择日期。在…

互斥量、读写锁长占时分析的利器——valgrind的DRD
在进行多线程编程时,我们可能会存在同时操作(读、写)同一份内存的可能性。为了保证数据的正确性,我们往往会使用互斥量、读写锁等同步方法。(转载请指明出于breaksoftware的csdn博客) 互斥量的用法如下 pth…

一次性同步修改多台linux服务器的密码
如何一次性修改多台linux服务器的密码,这是个问题,我给大家提供一个脚本,是前一段我刚刚写的,希望能对大家有所帮助一 , 需求:linux环境下运行,需要tcl和expect支持原理说明:利用expect的摸拟交互的功能&…
麻省理工学院的新系统TextFooler, 可以欺骗Google的自然语言处理系统及Google Home的音频...
来源 | news.mit编译 | 武明利责编 | Carol出品 | AI科技大本营(ID:rgznai100)两年前,Google的AI还不太成熟。一段时间以来,有一部分计算机科学研究一直致力于更好地理解机器学习模型如何处理这些“对抗性”攻击,这些攻…

Oracle VS DB2 数据类型
Oracle VS DB2 本文转自:http://www.bitscn.com/oracle/install/200604/16541.html首先,通过下表介绍ORACLE与DB2/400数据类型之间的对应关系,是一对多的关系,具体采用哪种对应关系,应具体问题具体分析。 OracleDB2/40…

死锁问题分析的利器——valgrind的DRD和Helgrind
在《DllMain中不当操作导致死锁问题的分析--死锁介绍》一文中,我们介绍了死锁产生的原因。一般来说,如果我们对线程同步技术掌握不牢,或者同步方案混乱,极容易导致死锁。本文我们将介绍如何使用valgrind排查死锁问题。(…
疫情可视化,基于知识图谱的AI“战疫”平台如何做?
来源 | DataExa渊亭科技武汉封城半个月,疫情依然严峻。但与17年前的SARS相比,我国在此次疫情防控工作中展现出了更高的医疗救治水平、更快的防疫反应速度、更透明的信息披露机制、更迅速的数据报送机制。在这场没有硝烟的战役中,社会各界团结…

mysql乐观锁总结和实践
2019独角兽企业重金招聘Python工程师标准>>> 上一篇文章《MySQL悲观锁总结和实践》谈到了MySQL悲观锁,但是悲观锁并不是适用于任何场景,它也有它存在的一些不足,因为悲观锁大多数情况下依靠数据库的锁机制实现,以保证操…

数据竞争(data race)问题分析的利器——valgrind的Helgrind
数据竞争(data race)是指在非线程安全的情况下,多线程对同一个地址空间进行写操作。一般来说,我们都会通过线程同步方法来保证数据的安全,比如采用互斥量或者读写锁。但是由于某些笔误或者设计的缺陷,还是存…

sql charindex函数
CHARINDEX函数返回字符或者字符串在另一个字符串中的起始位置。CHARINDEX函数调用方法如下: CHARINDEX ( expression1 , expression2 [ , start_location ] ) Expression1是要到expression2中寻找的字符中,start_location是CHARINDEX函数开始在expressi…
170亿参数加持,微软发布史上最大Transformer模型
来源 | 微软译者 | 刘畅出品 | AI科技大本营(ID:rgznai100)Turing Natural Language Generation(T-NLG)是微软提供的一个有170亿参数的语言模型,在许多NLP任务上均优于目前的SOTA技术。我们向学者演示了该模型…

iOS 开发 OC编程 数组冒泡排序.图书管理
// // main.m // oc -5 数组 // // Created by dllo on 15/10/28. // Copyright (c) 2015年 dllo. All rights reserved. // #import <Foundation/Foundation.h> #import "Student.h" #import "Book.h" int main(int argc, const char * argv[])…

C#中使用Monitor类、Lock和Mutex类来同步多线程的执行(转)
C#中使用Monitor类、Lock和Mutex类来同步多线程的执行 在多线程中,为了使数据保持一致性必须要对数据或是访问数据的函数加锁,在数据库中这是很常见的,但是在程序中由于大部分都是单线程的程序,所以没有加锁的必要,但是…
从0开始搭建编程框架——思考
需求来源于问题。(转载请指明出于breaksoftware的csdn博客) 之前有个人做前端开发的同学在群里问“C语言能做什么?能写网页么?”,然后大家就开始基于这个问题展开争辩。有的认为是“不能,从来没听说过C语言…
2月15日Python线上峰会免费学!6场精华分享,用代码“抗”疫
截至截止2月12号09时43分,新型冠状病毒在全国已确诊44726例,疑似病例已达21675例。而专家所说的“拐点”始终未至,受疫的影响,各大公司开启远程办公模式,将返回工作场所办公的时间一延再延。在抗疫前线,中国…

C#语言 数组
转载于:https://www.cnblogs.com/a849788087/p/4947939.html