对象池的实现与性能测试
作者:网络转载 发布时间:[ 2015/12/4 13:35:29 ] 推荐标签:软件测试 性能测试
引用对象池的好处:从池中操作对象比直接new、free要性能更快,且能避免内存碎片的堆积
先贴对象池的代码:
public abstract class ObjectBase
{
public abstract void Init(params object[] paramList);
}
//对象池管理器(采用堆栈存储,支持动态扩容,支持多线程,新扩容的则自动加入到池中能被重复利用)
public class ObjectPoolManager<T> where T : ObjectBase, new()
{
private static ObjectPoolManager<T> instance = null;
private int blockCapacity = 1000;
private static object doubleCheckLock = new object();
private static object objLock = new object();
private bool inited = false;
private ConcurrentDictionary<string, Stack<T>> objectPool = new ConcurrentDictionary<string, Stack<T>>();
private ObjectPoolManager() { }
public static ObjectPoolManager<T> Instance
{
get
{
if (instance == null)
{
lock (doubleCheckLock)
{
if (instance == null)
{
instance = new ObjectPoolManager<T>();
}
}
}
return instance;
}
}
//初始化对象池
public string Init(int blockCapacity)
{
lock (objLock)
{
try
{
if (blockCapacity < 1 || blockCapacity > int.MaxValue)
{
this.blockCapacity = 1000;
}
else
{
this.blockCapacity = blockCapacity;
}
Stack<T> freeObjList = new Stack<T>();
for (int index = 0; index < blockCapacity; index++)
{
T obj = new T();
freeObjList.Push(obj);
}
objectPool[typeof(T).ToString()] = freeObjList;
inited = true;
return null;
}
catch (Exception ex)
{
return typeof(T).ToString() + " -> ExceptionMessage:" + ex.Message + (ex.InnerException != null ? ("InnerExceptionMessage:" + ex.InnerException.Message) : "");
}
}
}
//取新对象
public T NewObject(params object [] paramList)
{
lock (objLock)
{
try
{
if (!inited)
{
Init(blockCapacity);
}
string key = typeof(T).ToString();
Stack<T> objList = objectPool[key];
if (objList.Count > 0)
{
T obj = objList.Pop();
obj.Init(paramList);
return obj;
}
else
{
for (int index = 0; index < this.blockCapacity; index++)
{
T newObj = new T();
objList.Push(newObj);
}
T obj = objList.Pop();
obj.Init(paramList);
return obj;
}
}
catch (Exception ex)
{
//ServerUtil.RecordLog(LogType.Error, ex);
T newObj = new T();
newObj.Init(paramList);
return newObj;
}
}
}
//释放对象
public void FreeObject(T obj)
{
lock (objLock)
{
try
{
if (obj == default(T)) return;
Stack<T> objList = objectPool[typeof(T).ToString()];
if (!objList.Contains(obj))
{
objList.Push(obj);
}
}
catch (Exception ex)
{
//ServerUtil.RecordLog(LogType.Error, ex);
}
}
}
}
下一步做与不用池时的性能测试对比:
先提供性能测试的支援函数
//使用方法见本文档末尾
public sealed class CodeElapseChecker
{
public static void Initialize()
{
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
Thread.CurrentThread.Priority = ThreadPriority.Highest;
Time("初始化性能测试工具,该值不用考虑", 1, () => { });
}
public static void Time(string name, Action action, int iterationCnt = 1)
{
Time(name, iterationCnt, action);
}
public static void Time(string name, int iteration, Action action)
{
// 1.
ConsoleColor currentForeColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(name);
// 2.
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
int[] gcCounts = new int[GC.MaxGeneration + 1];
for (int i = 0; i <= GC.MaxGeneration; i++)
{
gcCounts[i] = GC.CollectionCount(i);
}
// 3.
Stopwatch watch = new Stopwatch();
watch.Start();
long cycleCount = GetCycleCount();
for (int i = 0; i < iteration; i++) action();
long cpuCycles = GetCycleCount() - cycleCount;
watch.Stop();
// 4.
Console.ForegroundColor = currentForeColor;
Console.WriteLine(" Time Elapsed: " + watch.ElapsedMilliseconds.ToString("N0") + "ms");
Console.WriteLine(" CPU Cycles: " + cpuCycles.ToString("N0"));
// 5.
for (int i = 0; i <= GC.MaxGeneration; i++)
{
int count = GC.CollectionCount(i) - gcCounts[i];
Console.WriteLine(" Gen " + i + ": " + count);
}
Console.WriteLine();
}
private static long GetCycleCount()
{
//ulong cycleCount = 0;
//QueryThreadCycleTime(GetCurrentThread(), ref cycleCount);
//return cycleCount;
return GetCurrentThreadTimes();
}
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetThreadTimes(IntPtr hThread, out long lpCreationTime,
out long lpExitTime, out long lpKernelTime, out long lpUserTime);
private static long GetCurrentThreadTimes()
{
long l;
long kernelTime, userTimer;
GetThreadTimes(GetCurrentThread(), out l, out l, out kernelTime,
out userTimer);
return kernelTime + userTimer;
}
//[DllImport("kernel32.dll")]
//[return: MarshalAs(UnmanagedType.Bool)]
//static extern bool QueryThreadCycleTime(IntPtr threadHandle, ref ulong cycleTime);
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentThread();
}
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11