在C#中实现简单的对象池
当我们频繁创建删除大量对象的时候,对象的创建删除所造成的开销就不容小觑了。为了提高性能,我们往往需要实现一个对象池作为Cache:使用对象时,它从池中提取。用完对象时,它放回池中。从而减少创建对象的开销。
由于.net BCL库中并没有对象池的标准实现,因此需要我们自己去实现。好在实现功能简单的对象池并不麻烦,一般几十行代码就能实现。需要注意的一点是,对象池大多是需要支持多线程访问的,因此需要考虑线程安全问题。
在.Net 4.0后,BCL在System.Collections.Concurrent名字空间下引入了一系列线程安全的对象,微软甚至在MSDN上给了一个通过实现对象池的简单示例:How to: Create an Object Pool by Using a ConcurrentBag.
这个例子本身没有什么问题,但如果放在实际生产中就觉得有点简单过头了,一般还需要加上容量限制和重用时进行reset操作。这里我就稍微将其改了下:
public class ObjectPool<T>
{
ConcurrentBag<T> buffer;
Func<T> createFunc;
Action<T> resetFunc; public ObjectPool(Func<T> createFunc, Action<T> resetFunc, int capacity)
{
Contract.Assume(createFunc != null);
Contract.Assume(capacity > ); this.buffer = new ConcurrentBag<T>();
this.createFunc = createFunc;
this.resetFunc = resetFunc; this.Capacity = capacity;
} public int Capacity { get; private set; }
public int Count { get { return buffer.Count; } } /// <summary>
/// 申请对象
/// </summary>
public T GetObject()
{
var obj = default(T); if (!buffer.TryTake(out obj))
return createFunc();
else
return obj;
} /// <summary>
/// 释放对象
/// </summary>
public void PutObject(T obj)
{
Contract.Assume(obj != null); if (Count >= Capacity) //超过容量了,不再需要
return; if (resetFunc != null)
resetFunc(obj); buffer.Add(obj);
}
}
需要注意的是,我这里的实现并没有完全确保Capacity的绝对性:当两个线程同时往一个即将到达上限的对象池中放置对象时,可能都会成功。因为我觉得这个是没有太大必要的,感兴趣的朋友可以把它改下。
在C#中实现简单的对象池的更多相关文章
- Java网络与多线程系列之1:实现一个简单的对象池
前言 为什么要从对象池开始呢,先从一个网络IO操作的demo说起 比如下面这段代码,显而易见已经在代码中使用了一个固定大小的线程池,所以现在的重点在实现Runnble接口的匿名对象上,这个对象每次创建 ...
- Unity实现简单的对象池
一.简介 先说说为什么要使用对象池 在Unity游戏运行时,经常需要生成一些物体,例如子弹.敌人等.虽然Unity中有Instantiate()方法可以使用,但是在某些情况下并不高效.特别是对于那些需 ...
- 状态机模式中的Task与对象池
Task 抽象带来Task 首先,假设我们有这么一段逻辑:收到一个参数,先校验格式是否正确,再提取相关的参数出来,执行我们的事务,然后构建结果并返回.伪代码如下: /** * 一个engine类 ** ...
- Unity3D|-使用ScriptableObject脚本化对象来制作一个简单的对象池
ScriptableObject是一个用于生成单独Asset的结构.同时,它也能被称为是Unity中用于处理序列化的结构. 可以作为我们存储资源数据的有效方案.同时此资源可以作为我们AB包的有效资源! ...
- 【JVM】Java 8 中的常量池、字符串池、包装类对象池
1 - 引言 2 - 常量池 2.1 你真的懂 Java的“字面量”和“常量”吗? 2.2 常量和静态/运行时常量池有什么关系?什么是常量池? 2.3 字节码下的常量池以及常量池的加载机制 2.4 是 ...
- Java 中的对象池实现
点赞再看,动力无限.Hello world : ) 微信搜「程序猿阿朗 」. 本文 Github.com/niumoo/JavaNotes 和 未读代码博客 已经收录,有很多知识点和系列文章. 最近在 ...
- common-pool2对象池(连接池)的介绍及使用
我们在服务器开发的过程中,往往会有一些对象,它的创建和初始化需要的时间比较长,比如数据库连接,网络IO,大数据对象等.在大量使用这些对象时,如果不采用一些技术优化,就会造成一些不可忽略的性能影响.一种 ...
- 【h5-egret】深入浅出对象池
最近看到对象池这一块的东西,是频繁创建和删除类型游戏优化性能的一个解决方案. 简单来讲对象池就是个数组,把不用的对象放进去,因为数组还保存了对象的引用,所以对象不会被回收,等需要用的时候再从数组中取出 ...
- 用Java实现一个通用并发对象池
这篇文章里我们主要讨论下如何在Java里实现一个对象池.最近几年,Java虚拟机的性能在各方面都得到了极大的提升,因此对大多数对象而言,已经没有必要通过对象池来提高性能了.根本的原因是,创建一个新的对 ...
随机推荐
- lombok 去除麻烦的实体类get和set,toString书写
首先在pom.xml中添加 <dependency> <groupId>org.projectlombok</groupId> <artifactId> ...
- 内存cgroup
内存cgroup的值都是从哪里来的呀 page_counter_charge是增加page_counter的计数, try_charge函数和mem_cgroup_migrate函数是增加普通进程内存 ...
- hdu 2616 Kill the monster (DFS)
Kill the monster Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 圆盘自动机 cell
圆盘自动机 cell 一个n-m圆盘自动机,包含n个排列成一圈的方格,它们按1至n编号.每个方格中有一个整数,范围[0,m-1] .圆盘会进行d操作,每次d操作会使得每个方格中的数同时变换,变换为与其 ...
- Gcd反应堆 (pgcd)
Gcd反应堆 (pgcd) 题目描述 不知什么时候起,TA突然对gcd产生了浓厚的兴趣,于是他为此编写了个程序,输入分别不大于m,n (1<m,n<=10^7)的两个数,就能得出gcd(m ...
- bzoj 3111 蚂蚁 动态规划
题目描述 在一个 n*m 的棋盘上,每个格子有一个权值,初始时,在某个格子的顶点处一只面朝北的蚂蚁,我们只知道它的行走路线是如何转弯,却不知道每次转弯前走了多长. 蚂蚁转弯是有一定特点的,即它的转弯序 ...
- hybird app(混合式app开发)cordova ionic 创建相应平台的app
hybird app(混合式app开发) 之ionic 框架平台 guide cordova 创建相应平台的app 1. npm install -g cordova //全局安装cordova-cl ...
- web应用性能优化经验总结
常见性能优化要求 在我经历的性能优化案例中,常见的问题都是这样开始的: a) 前台访问很慢,请帮忙分析优化 b) 用户对性能很不满意,再不解决就要投诉 c) 数 ...
- 使用timeit模块 测试两种方式生成列表的所用的时间
from timeit import Timer def test(): li=[] for i in range(10000): li.append(i) def test2(): li=[i fo ...
- pymongo: MongoClient opened before fork错误排解
使用pymongo配合flask和gunicorn使用的时候触发以下错误信息: [2017-09-19 15:20: ] [25780] [CRITICAL] WORKER TIMEOUT (pid: ...