在传统的数据结构的实现中,分为侵入式容器和非侵入式容器两种

侵入式容器

这也是教材喜欢使用的数据结构的实现方式 ,将数据结构放入类中,所以先讲这个

非侵入式容器:

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)相关推荐

  1. 抢占式内核与非抢占式内核

    抢占式内核 与非抢占 式内核 linux抢占 式内核与实时系统的关系 一个好的系统的进程调度机制,要兼顾三种不同的应用的需求: 1交互式应用.这种应用,着重于系统的响应速度,当系统中有大量的进程共存时 ...

  2. linux之登录式shell和非登录式shell

    登录 shell 的途径 了解两种方式之间的区别,就要先了解 shell 的配置文件: bash 的配置文件 全局配置文件 /etc/profile /etc/profile.d/*.sh /etc/ ...

  3. 阻塞式IO和非阻塞式IO

    什么是阻塞式IO,什么是非阻塞式IO?区分他们有何用? 阻塞式IO:IO即input/output,阻塞式IO指的是"一旦输入/输出工作没有完成,则程序阻塞,直到输入/输出工作完成" ...

  4. 非侵入式监控php,非侵入式监控PHP应用性能监控分析

    前言 所谓非侵入式监控PHP应用性能,就是不修改现有系统代码,而对系统进行监控.这样的系统才能更容易的应用到PHP应用中.这里抛砖引玉,欢迎大家交流. 方案一 如果只是监控每次请求的访问时间.直接检测 ...

  5. 软件侵入式设计和非侵入式的区别

    在看书的时候经常看到"非侵入式设计",这样的名称,不太明白什么意思,特意百度了一番,记录一下,方便查阅,以防忘记. 设计理念不同 侵入式设计,就是设计者将框架功能"推&q ...

  6. 集成测试之增式集成测试和非增式集成测试

    集成测试的方法有两种: 非增式测试和增式测试 . 非渐增组装测试(非增式集成测试): 将单元测试后的模块按照总体的结构图一次性集成起来,然后把连接的整体进行程序测试. 即在短时间内把所有系统组件一次性 ...

  7. 监督式学习、 非监督式学习、强化学习

    Table of Contents 广义上来说,有3种机器学习算法 1. 监督式学习(Supervised Learning) 2. 非监督式学习(Unsupervised Learning) 3. ...

  8. 抢占式内核和非抢占式内核的区别

    内核抢占(可抢占式内核):即当进程位于内核空间时,有一个更高优先级的任务出现时,如果当前内核允许抢占,则可以将当前任务挂起,执行优先级更高的进程. 非抢占式内核:高优先级的进程不能中止正在内核中运行的 ...

  9. 抢占式内核与非抢占式内核的区别

    内核抢占(可抢占式内核): 即当进程位于内核空间时,有一个更高优先级的任务出现时,如果当前内核允许抢占,则可以将当前任务挂起,执行优先级更高的进程. 非抢占式内核: 高优先级的进程不能中止正在内核中运 ...

最新文章

  1. 访问级别约束0906
  2. h5 和native 交互那些事儿
  3. MySql8.0.16安装
  4. Android 人脸实名验证demo——腾讯人脸核身·云智慧眼
  5. Angular之jwt令牌身份验证
  6. mysql57服务无法启动_将mysqld.service服务加入到systemctl
  7. gganimate|让你的图动起来!!!
  8. Fogengine概述
  9. 数据库返回刚插入记录的ID
  10. 《自己动手写操作系统》 第一章总结
  11. 一文搞懂MEMS传感器产业链(最全解析!)
  12. 知弥深度清理大师隐私政策
  13. 单目深度估计综述(updating...)
  14. android studio实现记住密码,Andriod Studio实现保存QQ密码功能(案例代码详解)
  15. 中国黑客VS外国黑客,5分钟让你明白谁更技高一筹
  16. 怎么把图片格式转换成PDF呢?
  17. 远程办公何时了,网络打洞帮你搞
  18. php检索本地文件,神器:不仅秒搜本地文件,还能1秒在线检索文献!
  19. C语言函数:toupper
  20. sm2电子印章结构体

热门文章

  1. 2023江苏科技大学计算机考研信息汇总
  2. 259高校毕业设计选题
  3. seo和python_python网络爬虫与SEO搜索引擎优化介绍
  4. poj1442~优先队列oye
  5. 推荐富士通I2C接口FRAM芯片MB85RC16V
  6. curl 发送请求的几种示例
  7. android sqlite动态创建表,Android 解决sqlite无法创建新表的问题
  8. 电子计算机职业40201,天津二轻干部中等专业学校
  9. Unity下落式音游实现——(4)鼓盘动画及敲击判定
  10. 使用mybatis-plus产生java.sql.SQLSyntaxErrorException: Table ‘数据库.xxx表‘ doesn‘t exist(坑以踩)