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

侵入式容器

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

非侵入式容器:

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. php文件下载到服务器代码,PHP文件下载实例代码浅析
  2. tomca7.0 mysql配置连接池_tomcat7.0+mysql连接池配置
  3. 阻塞队列BlockingQueue
  4. Wireshark安装和基本使用
  5. C++中两个数交换不引进中间变量的方法
  6. mybatis insert插入成功返回0_mybatis添加客户
  7. 蓝桥杯 ALGO-89 算法训练 字符删除
  8. oracle 数组的用法,Oracle数组用法
  9. 无法在此设备上查看受保护内容_细说丨你想要的Excel保护与加密都在这里
  10. Ubuntu Git安装与使用
  11. word转HTML 基本版
  12. 玛咖新品牌 卡皇玛卡4月上市
  13. Spark学习笔记(一)
  14. Hive-003安装配置
  15. 30天自制操作系统第二天
  16. 网络安全系列-VIII: 什么是渗透测试 Penetration Test?
  17. 数学中常见的maxmin,min max
  18. 使用虚拟机备份软件备份XCP-ng虚拟机
  19. telnet连接工具无法连接到地址端口,报错无法打开到主机的连接。 在端口 23: 连接失败
  20. 短路与和短路或的区别

热门文章

  1. IEC 62471-6:2022 灯和灯光系统的光生物安全-第6部分:紫外线灯
  2. dell服务器开机蓝屏无限重启,Re: R720服务器不定期蓝屏自动重启
  3. MySQL数据库和Redis数据库
  4. Java: Object类,System类,StringBuilder类
  5. 3-多点温度采集模块设计--DS18B20驱动函数模块设计
  6. FPGA笔试问题知识点汇总(61~80)
  7. 安装Mysql-8.0.11遇到的问题
  8. 超详细TMS-EEG数据处理教程(上)
  9. 挑战类Flash游戏测试用例设计 [转]
  10. 使用s2i制作docker镜像