杭州软件测试培训
达内杭州软件测试培训中心

18357109557

热门课程

性能测试中对象池的实现方法

  • 时间:2015-12-08
  • 发布:杭州美工培训
  • 来源:51测试网


    杭州达内软件测试培训专家指出,引用对象池后,从池中操作对象比直接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);
}
}
}
}

    与不用对象池的性能测试的对比

    1.性能测试的支援函数

//使用方法见本文档末尾
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("\tTime Elapsed:\t" + watch.ElapsedMilliseconds.ToString("N0") + "ms");
Console.WriteLine("\tCPU Cycles:\t" + cpuCycles.ToString("N0"));
// 5.
for (int i = 0; i <= GC.MaxGeneration; i++)
{
int count = GC.CollectionCount(i) - gcCounts[i];
Console.WriteLine("\tGen " + i + ": \t\t" + 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();
}

    2.建立两个测试对象:

//复杂测试对象1
public class ComplexObject1 : ObjectBase
{
private byte[] data = new byte[1024];
public override void Init(params object[] paramList)
{
}
}
//复杂测试对象2
class ComplexObject2 : ObjectBase
{
private byte[] data = new byte[1024 * 1024];
public override void Init(params object[] paramList)
{
}
}

    3.测试代码: 

class Program
{
const int Count1 = 1000000;
const int Count2 = 500;
static void Main(string[] args)
{
var list1 = new List<ComplexObject1>(Count1 * 2);
var list2 = new List<ComplexObject2>(Count2 * 2);
CodeElapseChecker.Initialize();
ObjectPoolManager<ComplexObject1>.Instance.Init(Count1);
ObjectPoolManager<ComplexObject2>.Instance.Init(Count2);
CodeElapseChecker.Time("TestComplexObject1", () => { list1.Add(new ComplexObject1()); }, Count1);
CodeElapseChecker.Time("TestPooledComplexObject1", () => { list1.Add(ObjectPoolManager<ComplexObject1>.Instance.NewObject()); }, Count1);
CodeElapseChecker.Time("TestComplexObject2", () => { list2.Add(new ComplexObject2()); }, Count2);
CodeElapseChecker.Time("TestPooledComplexObject2", () => { list2.Add(ObjectPoolManager<ComplexObject2>.Instance.NewObject()); }, Count2);
Console.WriteLine(list1.Count);
Console.WriteLine(list2.Count);
}
}

    4.运行测试结果


上一篇:测试工程师的职业发展规划
下一篇:达内三大少儿品牌亮相教育博览会,趣味教学受青睐

WEB安全探测框架——Recon-ng

达内:测试用例中的电子邮箱文本框

达内介绍iOS功能性UI测试框架EarlGrey

达内:python的web应用开发与测试

选择城市和中心
贵州省

广西省

海南省