posts - 76, comments - 26, trackbacks - 0

Reflection Speed Tests

I frequently hear claims that Reflection in .NET is slow.  The discovery of the various metadata element of a type definitely is expensive, but after that cost is incurred, is the invocation of those elements any slower than native code?  I’ve often wondered, but never did any tests of my own.

Here is one quick speed test:

SpeedWriter

    public class SpeedWriter : IDisposable
    {
        private readonly Stopwatch _watch = new Stopwatch();
        private readonly string _description;

        public SpeedWriter(string description)
        {
            _description = description;
            _watch.Start();
        }

        public void Dispose()
        {
            _watch.Stop();

            long duration = _watch.ElapsedMilliseconds;

            Console.WriteLine(string.Format("{0} -- Milliseconds: {1}", _description, duration));
        }
    }

Foo

Some silly object that I can act upon in my tests

    public class Foo
    {
        public string Bar { get; set; }

        public void DoSomething(int x, int y)
        {
            // do something that the compiler won't optimize away
            int sum = x + y;

            if ( sum > 1000 )
            {
                Console.WriteLine("You're exceeded 100!");
            }

        }
    }

 

DoReflectionTest

        private static void DoReflectionTest()
        {
            Console.WriteLine("--------------- Reflection Test Begin ------------------");
                        
            PropertyInfo property = typeof (Foo).GetProperty("Bar");
            MethodInfo method = typeof (Foo).GetMethod("DoSomething");

            Foo foo = new Foo();

            using ( new SpeedWriter("Foo.Bar Setter Test..."))
            {
                int counter = 0;

                while ( counter < 1000 ) // do this a few times
                {
                    property.SetValue(foo, Guid.NewGuid().ToString(), null);
                    counter++;
                }
            }

            using (new SpeedWriter("Foo.Bar Getter Test..."))
            {
                int counter = 0;

                while (counter < 1000) // do this a few times
                {
                    property.GetValue(foo, null);
                    counter++;
                }
            }
            
            using (new SpeedWriter("Foo.Write Method-Invoke Test..."))
            {
                int counter = 0;

                while (counter < 1000) // do this a few times
                {
                    method.Invoke(foo, new object[] { counter, 1 } );
                    counter++;
                }
            }

            Console.WriteLine("---------------- Reflection Test End -------------------");
        }

DoNativeCodeTest

        private static void DoNativeCodeTest()
        {

            Console.WriteLine("--------------- Native Code Test Begin ------------------");

            Foo foo = new Foo();

            using (new SpeedWriter("Foo.Bar Setter Test..."))
            {
                int counter = 0;

                while (counter < 1000) // do this a few times
                {
                    foo.Bar = Guid.NewGuid().ToString();
                    counter++;
                }
            }

            using (new SpeedWriter("Foo.Bar Getter Test..."))
            {
                int counter = 0;

                while (counter < 1000) // do this a few times
                {
                    string bar = foo.Bar;
                    counter++;
                }
            }

            using (new SpeedWriter("Foo.Write Method-Invoke Test..."))
            {
                int counter = 0;

                while (counter < 1000) // do this a few times
                {
                    foo.DoSomething(counter, 1);
                    counter++;
                }
            }

            Console.WriteLine("---------------- Native Code Test End -------------------");
        }

 

Conclusion

There’s definitely a difference:

image

I’d like to do some more tests to better understand the difference precisely.  I’d also like to create a test case for a dynamic-method implementation to see how close it is to native code.

Print | posted on Tuesday, January 27, 2009 7:36 AM |

Feedback

No comments posted yet.

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 5 and 4 and type the answer here:

Powered by: