c++实现,对象池 object_pool
简言
1. boost的对象池object_pool在释放时采用的遍历,有性能问题
2. 也不是什么大问题,优化后可用。但是仅仅为了一个对象池,引入boost,没必要
3. 笔者这里一份简单实现的对象池,windows和linux下通用
4. 代码量很小,仅仅两百行,支持对象池高峰过后,逐步回收
接口介绍
1. // 初始化(初始数量,一次增长的数量, 单次收缩的数量)
bool init(int initNum = 200, int increaseNum = 100, int reduceNum = 50);
2. // 分配一个新对象
T* alloc();
3. // 回收一个对象
void dealloc(T* pObj);
4. // 执行一次回收,用来使用高峰过后的缩减
void dorecycle();
代码下载地址
windows版:https://download.csdn.net/download/yzf279533105/11989303
实验如下图(特意标记出来两次回收之后的,每次回收50个,空闲列表free_list的数量)
完整代码
#pragma once#include <unordered_set>
#include <string.h>//对象池模板类
template<class T>
class class_obj_pool
{
public:enum{MAX_INIT_NUM = 100000, // 初始化最大数量,暂定10万};class_obj_pool(){clear();}~class_obj_pool(){clear();}
public:// 初始化(初始数量,一次增长的数量, 单次收缩的数量)bool init(int initNum = 200, int increaseNum = 100, int reduceNum = 50){// 参数检测if (initNum <= 0 || increaseNum <= 0 || reduceNum <= 0){printf("init(), param error, initNum=%d, nIncreaseNum=%d, reduceNum=%d\n", initNum, increaseNum, reduceNum);return false;}nInitNum = initNum;nIncreaseNum = increaseNum;nShrinkNum = reduceNum;// 参数修正nInitNum = nInitNum>MAX_INIT_NUM ? MAX_INIT_NUM : nInitNum; // 初始个数nIncreaseNum = nIncreaseNum>MAX_INIT_NUM ? MAX_INIT_NUM : nIncreaseNum; // 一次增长的数量// 初始化对象for (int i = 0; i<nInitNum; ++i){T* pObj = new(std::nothrow)T();if (pObj == NULL){printf("new obj failed \n");continue;}// T对象需提供init函数进行初始化if (pObj->init() == false){printf("pObj->init() failed \n");delete pObj;continue;}free_list.insert(pObj);}return true;}// 分配一个新对象T* alloc(){T* pRet = NULL;// 空闲列表中有,则取一个if (free_list.size() > 0){unordered_set<T*>::iterator iter = free_list.begin();pRet = *iter;free_list.erase(iter);used_list.insert(pRet);// 超过最大使用记录量,则更新if (used_list.size() > nUsedMax){nUsedMax = used_list.size();}return pRet;}// 空闲列表中没有时,则新建一批for (int i = 0; i<nIncreaseNum; i++){T* pObj = new(std::nothrow)T();if (pObj == NULL){printf("alloc(), new obj failed \n");continue;}// T对象需提供init函数进行初始化if (pObj->init() == false){printf("pObj->init() failed \n");delete pObj;continue;}// 没赋值的先赋值;已赋值的压入空闲列表if (pRet == NULL){pRet = pObj;used_list.insert(pObj);}else{free_list.insert(pObj);}}// 超过最大使用记录量,则更新if (used_list.size() > nUsedMax){nUsedMax = used_list.size();}return pRet;}// 回收一个对象void dealloc(T* pObj){if (pObj == NULL){printf("dealloc(), pObj == NULL");return;}// 不存在unordered_set<T*>::iterator it = used_list.find(pObj);if (it == used_list.end()){printf("dealloc(), find pObj failed \n");return;}// T对象需提供reset()函数进行重置pObj->reset();free_list.insert(pObj);used_list.erase(pObj);}// 执行一次回收,用来使用高峰过后的缩减void dorecycle(){// 空闲列表中有对象,且超过一次增量时,才进行回收int nfree = free_list.size();if (nfree <= nIncreaseNum){return;}// 要回收的数量nfree = (nfree - nIncreaseNum);int i = 0;for (unordered_set<T*>::iterator iter = free_list.begin(); iter != free_list.end();){T* pObj = *iter;if (pObj != NULL){delete pObj;}free_list.erase(iter++);// 超过一次回收的最大量,就跳出i++;if (i>=nShrinkNum){break;}}}// 打印出各个变量void showinfo(){printf("free_list.size=%d, used_list.size=%d, nUsedMax=%d \n", free_list.size(), used_list.size(), nUsedMax);}// 回收void clear(){for (std::unordered_set<T*>::iterator iter = free_list.begin(); iter != free_list.end(); iter++){T* pObj = *iter;if (pObj != NULL){delete pObj;}}free_list.clear();for (std::unordered_set<T*>::iterator iter = used_list.begin(); iter != used_list.end(); iter++){T* pObj = *iter;if (pObj != NULL){delete pObj;}}used_list.clear();nInitNum = 0; // 初始个数nUsedMax = 0; // 曾经使用的最大个数nIncreaseNum = 0; // 一次增长的数量nShrinkNum = 0; // 单次回收的最大数量}
private:std::unordered_set<T*> free_list; // 空闲列表std::unordered_set<T*> used_list; // 使用中的列表int nInitNum; // 初始个数int nUsedMax; // 曾经使用的最大个数int nIncreaseNum; // 一次增长的数量int nShrinkNum; // 单次回收的最大数量
};
c++实现,对象池 object_pool相关推荐
- python求5_python(五)——运算符,小整数对象池
1.成员运算符,判断某个东西是否在某个东西里包含:in,not in name = "abcd" if "ac" inname:print("ok&q ...
- 面试官问:对象池技术了解吗?apache common pool2呢?
欢迎关注方志朋的博客,回复"666"获面试宝典 对象池顾名思义就是存放对象的池,与我们常听到的线程池.数据库连接池.http连接池等一样,都是典型的池化设计思想. 对象池的优点就是 ...
- golang的临时对象池sync.Pool
今天在写码之时,发现了同事用到了sync.pool.因不知其因,遂Google之.虽然大概知道其原因和用法.还不能融汇贯通.故写此记,方便日后查阅.直至明了. 正文 在高并发或者大量的数据请求的场景中 ...
- 转载 Xmlhttprequest对象池
2019独角兽企业重金招聘Python工程师标准>>> 在ajax应用中,通常一个页面要同时发送多个请 求,如果只有一个XMLHttpRequest对象,前面的请求还未完成,后面的就 ...
- [转]建一个XMLHttpRequest对象池
在ajax应用中,通常一个页面要同时发送多个请求,如果只有一个XMLHttpRequest对象,前面的请求还未完成,后面的就会把前面的覆盖掉,如果每次都创建一个新的XMLHttpRequest对象,也 ...
- Unity中对象池的使用
unity中用到大量重复的物体,例如发射的子弹,可以引入对象池来管理,优化内存. 对象池使用的基本思路是: 将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用.恰当地使用对象池,可以在 ...
- Java 程序优化之对象池
对象池概念: 如果一个类被频繁请求使用,那么不必每次都生成一个实例,可以将这个类都一些实例保存到一个"池"中,待需要使用的时候直接从"池"中获取.这个" ...
- python整数池_【Python】Python中神奇的小整数对象池和大整数对象池
小整数对象池 整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间. Python 对小整数的定义是 [-5, 256] 这些整数对象是提前建立 ...
- cocos对象池的使用
enemy.js cc.Class({extends: cc.Component,properties: {enemySpeed: 0, //设置加速度 },//初始化当前节点的y坐标init: fu ...
最新文章
- 了解 ElasticSearch 这几个知识点后,查询起飞~
- python的四种内置数字类型_浅析Python数字类型和字符串类型的内置方法
- 找不到 tools.jar。请检查 C:\Program Files\Java\jre1.8.0_151 是否包含有效的 JDK 安装
- 【python】python redis的安装与使用
- 汉字笔画数据_把所有汉字叠起来会怎样?
- 前端学习(2820):全局文件tabber字段
- TF下载量已超4600万!首届TensorFlow World大会,谷歌大牛Jeff Dean激情演讲
- RMAN备份与恢复(三)--备份相关概念
- 在3.5下实现无配置WCF服务
- Indent Guides插件格式代码
- 精通git中文版 (连载四)
- 【全网最简单】给朋友- 制作,微信公众号推送教程
- 京东智能客服言犀启发式问答技术探秘
- 【爬虫】抓取msdn.itellyou.cn所有操作系统镜像下载链接
- Mac如何查看系统根目录
- Java多用户商城源码/单商户商城系统源码
- 计算n个整数中有多少个正整数、多少个负整数,并计算这些整数的总和和平均值
- C++PrimerPlus
- Android在CMD中输入adb命令,提示“'adb' 不是内部或外部命令,也不是可运行的程序”的解决方法
- 2019最新《传智教育黑马java项目实战》
热门文章
- Cisco SSL ×××
- .Net 事件类型的实现和推荐做法
- CodeForces - 985F Isomorphic Strings(字符串哈希)
- (转)快速统计二进制中1的个数
- CH - 0104 起床困难综合症(位运算+贪心)
- 广度优先遍历算法-03树的右侧问题
- mysql avg 报错_MySQL报错汇总
- 《qss样式表笔记大全(二):可设置样式的窗口部件列表(上)(包含相关示例)》
- live555 源码分析:ServerMediaSession
- C++ 面向对象(三)异常 :异常概念、异常的匹配规则、异常安全、异常体系