Skip to content

Instantly share code, notes, and snippets.

@hach-que
Last active August 29, 2015 14:04
Show Gist options
  • Save hach-que/7a5057f1c45c01097048 to your computer and use it in GitHub Desktop.
Save hach-que/7a5057f1c45c01097048 to your computer and use it in GitHub Desktop.
////////// Program.cs /////////////
#if PLATFORM_WINDOWS || PLATFORM_MACOS || PLATFORM_LINUX || PLATFORM_WEB
namespace PoolingTest
{
using Ninject;
using System;
using System.Diagnostics;
using Protogame;
using Monocle;
public static class Program
{
public static void Main(string[] args)
{
// First run.
Console.WriteLine("Testing setup access:");
for (var test = 0; test < 10; test++)
{
var protogamePoolFirstRunStopwatch = Stopwatch.StartNew();
var protogamePoolManager = new DefaultPoolManager();
var protogamePool = protogamePoolManager.NewPool<TestObject>("pool", 10000, x => {});
protogamePoolFirstRunStopwatch.Stop();
var monoclePoolerFirstRunStopwatch = Stopwatch.StartNew();
var monoclePooler = new Pooler();
for (var i = 0; i < 10000; i++)
{
var obj = monoclePooler.Create<TestObject>();
monoclePooler.EntityRemoved(obj);
}
monoclePoolerFirstRunStopwatch.Stop();
Console.WriteLine("Protogame pool first run: " + protogamePoolFirstRunStopwatch.Elapsed);
Console.WriteLine("Monocle pool first run: " + monoclePoolerFirstRunStopwatch.Elapsed);
}
Console.WriteLine("Testing runtime access:");
{
var protogamePoolManager = new DefaultPoolManager();
var protogamePool = protogamePoolManager.NewPool<TestObject>("pool", 10000, x => {});
var monoclePooler = new Pooler();
for (var i = 0; i < 10000; i++)
{
var obj = monoclePooler.Create<TestObject>();
monoclePooler.EntityRemoved(obj);
}
for (var test = 0; test < 10; test++)
{
var monoclePoolerFirstRunStopwatch = Stopwatch.StartNew();
for (var run = 0; run < 10; run++)
{
for (var i = 0; i < 10000; i++)
{
var obj = monoclePooler.Create<TestObject>();
monoclePooler.EntityRemoved(obj);
}
}
monoclePoolerFirstRunStopwatch.Stop();
var protogamePoolFirstRunStopwatch = Stopwatch.StartNew();
for (var run = 0; run < 10; run++)
{
for (var i = 0; i < 10000; i++)
{
var obj = protogamePool.Get();
protogamePool.Release(obj);
}
}
protogamePoolFirstRunStopwatch.Stop();
Console.WriteLine("Protogame pool run: " + protogamePoolFirstRunStopwatch.Elapsed);
Console.WriteLine("Monocle pool run: " + monoclePoolerFirstRunStopwatch.Elapsed);
}
}
}
}
}
#endif
////////// Pooler.cs /////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Monocle
{
public class Pooler
{
internal Dictionary<Type, Queue<object>> Pools { get; private set; }
public Pooler()
{
Pools = new Dictionary<Type, Queue<object>>();
foreach (var type in Assembly.GetEntryAssembly().GetTypes())
{
if (type.GetCustomAttributes(typeof(Pooled), false).Length > 0)
{
if (!typeof(object).IsAssignableFrom(type))
throw new Exception("Type '" + type.Name + "' cannot be Pooled because it doesn't derive from Entity");
else if (type.GetConstructor(Type.EmptyTypes) == null)
throw new Exception("Type '" + type.Name + "' cannot be Pooled because it doesn't have a parameterless constructor");
else
Pools.Add(type, new Queue<object>());
}
}
}
public void Log()
{
foreach (var kv in Pools)
{
string output = kv.Key.Name + " : " + kv.Value.Count;
}
}
public T Create<T>() where T : class, new()
{
#if DEBUG
if (!Pools.ContainsKey(typeof(T)))
throw new Exception("The provided Entity type is not a Pooled type");
#endif
var stack = Pools[typeof(T)];
if (stack.Count == 0)
{
return new T();
}
else
{
return stack.Dequeue() as T;
}
}
public void EntityRemoved(object entity)
{
var type = entity.GetType();
if (Pools.ContainsKey(type))
Pools[type].Enqueue(entity);
}
}
public class Pooled : Attribute
{
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment