Willkommen | HowTo | Referenzen | Impressum
Kersting it-solutions the sharper way
  # HowTo  


04/12/2004
How to speed up reflection little bit.

This little code example shows you how to cache reflection results and thereby getting some better performance. Imagine you have an application where you repeatingly need to request all public methods of certain types. Of course that's easy, you will just call Type.GetMethods() whereever you need it and that's it. But if you have a fixed amount of types you could avoid using reflection ever and ever again.

The sourcecode below shows you how to develop a small cache to store the results of reflection. The cache checks first of all if incoming request type is already well known. if so, request is served from cache. if not - and only if not - reflection is used.

To demonstrate performance you will also find little routine below which tests direct calls vs. cached calls.  As you can see the cached routine is ~10 times faster! Nice result for just a few additional lines of code.

Console output will look like this:

ReflectionExample started...

uncached, elapsed time: 00:00:00.8111664
cached, elapsed time: 00:00:00.0801152

press any key to exit...

Here is the code:

using System;
using System.Collections;
using System.Reflection;
namespace ReflectionExample
{
	public class ReflectionCache
	{
		// singleton
		public static ReflectionCache Instance = new ReflectionCache();
		private Hashtable list = new Hashtable();
		private ReflectionCache()
		{
		}
		// get methods for specified type
		public MethodInfo[] GetMethods(Type type)
		{
			if(!list.ContainsKey(type))
			{
				// type was not found, so call reflection and store the result
				// in the list for next time
				list[type] = type.GetMethods();
			}
			// serve request from list
			return (MethodInfo[])list[type];
		}
	}
}

using System;
using System.Collections;
using System.Reflection;
namespace ReflectionExample
{
	class Class1
	{
		[STAThread]
		static void Main(string[] args)
		{
			Console.WriteLine("ReflectionExample started...\n");
			testUncached();
			testCached();
			Console.WriteLine("\npress any key to exit...");
			Console.ReadLine();
		}
		private static int loops = 100000;
		private static DateTime start;
		private static DateTime stop;
		private static TimeSpan diff;
		private static Type[] testTypes = new Type[] 
			{ typeof(ArrayList), typeof(SortedList), typeof(Hashtable) };
		private static void testUncached()
		{
			start = DateTime.Now;
			for(int i=0; i<loops; i++)
			{
				testTypes[0].GetMethods();
				testTypes[1].GetMethods();
				testTypes[2].GetMethods();
			}
			stop = DateTime.Now;
			diff = stop - start;
			Console.WriteLine("uncached, elapsed time: " + diff.ToString());
		}
		private static void testCached()
		{
			start = DateTime.Now;
			for(int i=0; i<loops; i++)
			{
				ReflectionCache.Instance.GetMethods(testTypes[0]);
				ReflectionCache.Instance.GetMethods(testTypes[1]);
				ReflectionCache.Instance.GetMethods(testTypes[2]);
			}
			stop = DateTime.Now;
			diff = stop - start;
			Console.WriteLine("cached, elapsed time: " + diff.ToString());
		}
	}
}