深入理解侵入式容器与非侵入式容器(intrusive containers)
在传统的数据结构的实现中,分为侵入式容器和非侵入式容器两种
侵入式容器
这也是教材喜欢使用的数据结构的实现方式 ,将数据结构放入类中,所以先讲这个
非侵入式容器:
struct ListNode {ListNode *prev, *next;int value;
};
这时候如果要用模板实现的话就是:
template <typename T>
struct ListNode {ListNode *prev, *next;T value;
};
可以看见数据都是放在类中,这也是平常在教学中常用的数据结构组织方式
非侵入式容器
C++标准的STL库中实现的容器,甚至于Redis中实现的容器都是非侵入式容器
关于在linux的kernel/inclue/linux/types.h源码中链表的实现:
struct list_head {struct list_head *next, *prev;
};
看一看这个数据结构表示中,只在里面存储了数据类型的前驱节点和后驱节点
这时候,如果想要存储数据,需要创建指定的数据结构
Struct node{int sum;list_head list;
}
这时候的数据结构示意图如下:
关于Ridis的adlist.h源码中:
typedef struct listNode {struct listNode *prev;struct listNode *next;void *value;
} listNode;
在value中通过一个指针指向存储数据结构的区域
这时候,可以实现一个数据结构比如说struct
struct A{int data;
}
这时候需要用指针读到这个数据结构:
listNode *Node;
int v =(int*)Node->value;
非侵入式容器总结和优势
可有看到再以上的非侵入式容器中数据没有直接放入类中,这样存储有什么好处呢?
这样存储数据类型有着非常的灵活性,解耦了容器和数据
比如说把
typedef struct listNode {struct listNode *prev;struct listNode *next;void *value;
} listNode;
放入h文件中
把
struct A{int data;
}
放入cpp文件后
每次编译的时候,h文件需要全部复制到cpp文件中
这时候,如果修改类存储的数据结构的时候,放如果使用侵入式的方法,就会发现,h中改动一下,就要重新编译好久,单数放在cpp中,就会使得编译的流程大大减少
另一方面:
非入侵式容器不需要使用模板泛型编程,但是这不意味着彻底抛弃模板,在boost库的intrusive中就需要使用typename
侵入式容器总结和优势
在非侵入式容器中,每回寻找数据需要指针再次定位,但在现在的电脑上,这点性能开销简直可以忽略不记
创建需要在两个空间上new两次,其实也影响不大
其实它最不好地方在于在松散的内存布局对于cache line及其不友好
那么侵入式容器的优势就出来了,可以使得内存紧密排列,从而提高chache的命中率
另外重要的一点就是:
在STL的容器都是使用allocator分配器,如果使用侵入式容器,由于调用关系数据只能分配在堆上面
但是如果使用了侵入式容器的话,数据可以分配在栈上面,例如使用plancement new
在EASTL库中(由于游戏的特殊性,一般游戏需要构建自己的内存池,所以EASTL这套EA开发的高性能库成了不烧游戏开发的选择),就提供了intrusive容器的使用
扩展:从容器到侵入式和非侵入式框架设计
侵入式框架:引入了框架,对现有的类的结构有影响,需要实现框架某些接口或者基础某些特定的类。
非侵入式框架:引入了框架,对现有的类结构没有影响,不需要实现框架某些接口或者特定的类。
现在sprinresprinredis的框架设计倾向于非侵入式框架,这源于代码设计高内聚,低耦合原则
就拿spring举例吧,在java常用的spring框架中,就是常用的非侵入式框架设计,利用反射和动态调节涌来实例化对象,代码中没有与spring耦合交叉的类,这时候完全可以换一套框架,但是对原来的代码没影响,这么说当然夸张了,有一点侵入还是有的
深入理解侵入式容器与非侵入式容器(intrusive containers)相关推荐
- 抢占式内核与非抢占式内核
抢占式内核 与非抢占 式内核 linux抢占 式内核与实时系统的关系 一个好的系统的进程调度机制,要兼顾三种不同的应用的需求: 1交互式应用.这种应用,着重于系统的响应速度,当系统中有大量的进程共存时 ...
- linux之登录式shell和非登录式shell
登录 shell 的途径 了解两种方式之间的区别,就要先了解 shell 的配置文件: bash 的配置文件 全局配置文件 /etc/profile /etc/profile.d/*.sh /etc/ ...
- 阻塞式IO和非阻塞式IO
什么是阻塞式IO,什么是非阻塞式IO?区分他们有何用? 阻塞式IO:IO即input/output,阻塞式IO指的是"一旦输入/输出工作没有完成,则程序阻塞,直到输入/输出工作完成" ...
- 非侵入式监控php,非侵入式监控PHP应用性能监控分析
前言 所谓非侵入式监控PHP应用性能,就是不修改现有系统代码,而对系统进行监控.这样的系统才能更容易的应用到PHP应用中.这里抛砖引玉,欢迎大家交流. 方案一 如果只是监控每次请求的访问时间.直接检测 ...
- 软件侵入式设计和非侵入式的区别
在看书的时候经常看到"非侵入式设计",这样的名称,不太明白什么意思,特意百度了一番,记录一下,方便查阅,以防忘记. 设计理念不同 侵入式设计,就是设计者将框架功能"推&q ...
- 集成测试之增式集成测试和非增式集成测试
集成测试的方法有两种: 非增式测试和增式测试 . 非渐增组装测试(非增式集成测试): 将单元测试后的模块按照总体的结构图一次性集成起来,然后把连接的整体进行程序测试. 即在短时间内把所有系统组件一次性 ...
- 监督式学习、 非监督式学习、强化学习
Table of Contents 广义上来说,有3种机器学习算法 1. 监督式学习(Supervised Learning) 2. 非监督式学习(Unsupervised Learning) 3. ...
- 抢占式内核和非抢占式内核的区别
内核抢占(可抢占式内核):即当进程位于内核空间时,有一个更高优先级的任务出现时,如果当前内核允许抢占,则可以将当前任务挂起,执行优先级更高的进程. 非抢占式内核:高优先级的进程不能中止正在内核中运行的 ...
- 抢占式内核与非抢占式内核的区别
内核抢占(可抢占式内核): 即当进程位于内核空间时,有一个更高优先级的任务出现时,如果当前内核允许抢占,则可以将当前任务挂起,执行优先级更高的进程. 非抢占式内核: 高优先级的进程不能中止正在内核中运 ...
最新文章
- 访问级别约束0906
- h5 和native 交互那些事儿
- MySql8.0.16安装
- Android 人脸实名验证demo——腾讯人脸核身·云智慧眼
- Angular之jwt令牌身份验证
- mysql57服务无法启动_将mysqld.service服务加入到systemctl
- gganimate|让你的图动起来!!!
- Fogengine概述
- 数据库返回刚插入记录的ID
- 《自己动手写操作系统》 第一章总结
- 一文搞懂MEMS传感器产业链(最全解析!)
- 知弥深度清理大师隐私政策
- 单目深度估计综述(updating...)
- android studio实现记住密码,Andriod Studio实现保存QQ密码功能(案例代码详解)
- 中国黑客VS外国黑客,5分钟让你明白谁更技高一筹
- 怎么把图片格式转换成PDF呢?
- 远程办公何时了,网络打洞帮你搞
- php检索本地文件,神器:不仅秒搜本地文件,还能1秒在线检索文献!
- C语言函数:toupper
- sm2电子印章结构体
热门文章
- 2023江苏科技大学计算机考研信息汇总
- 259高校毕业设计选题
- seo和python_python网络爬虫与SEO搜索引擎优化介绍
- poj1442~优先队列oye
- 推荐富士通I2C接口FRAM芯片MB85RC16V
- curl 发送请求的几种示例
- android sqlite动态创建表,Android 解决sqlite无法创建新表的问题
- 电子计算机职业40201,天津二轻干部中等专业学校
- Unity下落式音游实现——(4)鼓盘动画及敲击判定
- 使用mybatis-plus产生java.sql.SQLSyntaxErrorException: Table ‘数据库.xxx表‘ doesn‘t exist(坑以踩)