Reflection test does not show expected numbers

I wrote some test codes to compare the performance of using direct access to properties or reflection or reflection using delegates. But the results that I get are confusing, since it shows that reflection is not much slower (~ 4%) than direct access to properties, which I do not consider true. Can someone tell me that I am doing something wrong here?


for 5000 elements I get below results

  • direct access: 32.2609 sec.
  • reflection: 33.623 seconds of reflection
  • using delegates: 31.7981 seconds

the code:

private static Random random = new Random((int)DateTime.Now.Ticks);
Private Dictionary<string, Delegate> delegateList = new Dictionary<string, Delegate>(); 
private List<ReflectClass1> dataList = new List<ReflectClass1>();

    private void TestMethod2<T>()
    {
        foreach (var propertyInfo in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            if (propertyInfo.PropertyType.BaseType != typeof(ValueType))
            {
                Func<T, object> getPropDelegate =
                    (Func<T, object>) Delegate.CreateDelegate(typeof (Func<T, object>), null, propertyInfo.GetGetMethod());
                delegateList.Add(propertyInfo.Name, getPropDelegate);
            }
            //else
            //{
            //    Type propertyType = propertyInfo.PropertyType.GetType();
            //    delegateList.Add(propertyInfo.Name,
            //                     Delegate.CreateDelegate(typeof(Func<T, TResult>), null, propertyInfo.GetGetMethod()));
            //}
        }
    }
    //http:_//stackoverflow.com/questions/1122483/c-random-string-generator     
    private string RandomString(int size)
    {
        StringBuilder builder = new StringBuilder();
        char ch;
        for (int i = 0; i < size; i++)
        {
            ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
            builder.Append(ch);
        }

        return builder.ToString();
    }

    private void SetUpReflectObjList()
    {
        for (int i = 0; i < 5000 ; i++)
        {
            ReflectClass1 reflectClass1 = new ReflectClass1();
            reflectClass1.Prop1 = RandomString(15);
            reflectClass1.Prop2 = RandomString(10);
            reflectClass1.Prop3 = RandomString(10);
            reflectClass1.Prop4 = RandomString(10);
            reflectClass1.Prop5 = RandomString(10);
            reflectClass1.Prop6 = RandomString(10);
            reflectClass1.Prop7 = RandomString(10);
            reflectClass1.Prop8 = RandomString(10);
            reflectClass1.Prop9 = RandomString(10);
            reflectClass1.Prop10 = RandomString(10);
            dataList.Add(reflectClass1);
        }
    }

    private void UseDelegateList()
    {
        Debug.WriteLine(string.Format(" Begin delegate performance test. item count = {0} start time: {1}",dataList.Count, DateTime.Now.ToLongTimeString()));
        for (int i = 0; i < dataList.Count; i++)
        {
            foreach (PropertyInfo propertyInfo in typeof(ReflectClass1).GetProperties())
            {
                if (delegateList.ContainsKey(propertyInfo.Name))
                {
                    Func<ReflectClass1, object> getPropDelegate = (Func<ReflectClass1, object>) delegateList[propertyInfo.Name];
                    Debug.Write(string.Format(" By delegates Object: {0} Property: {1} Value: {2}", i, propertyInfo.Name, getPropDelegate(dataList[i])));
                }
            }
        }
        Debug.WriteLine("");
        Debug.WriteLine(string.Format(" End delegate performance test. item count = {0} end time: {1}", dataList.Count, DateTime.Now.ToLongTimeString()));
    }

    private void UseDirectReflection()
    {
        Debug.WriteLine(string.Format(" Begin direct reflection performance test. item count = {0} start time: {1}", dataList.Count, DateTime.Now.ToLongTimeString()));
        for (int i = 0; i < dataList.Count; i++)
        {
            foreach (PropertyInfo propertyInfo in typeof(ReflectClass1).GetProperties())
            {
                if (propertyInfo == null) continue;
                {
                    Debug.Write(string.Format(" By reflection Object: {0} Property: {1} Value: {2}", i, propertyInfo.Name, propertyInfo.GetValue(dataList[i], null)));
                }
            }
        }
        Debug.WriteLine("");
        Debug.WriteLine(string.Format(" End direct reflection performance test. item count = {0} end time: {1}", dataList.Count, DateTime.Now.ToLongTimeString()));
    }

    private void DirectOutputTest()
    {
        Debug.WriteLine(string.Format(" Begin direct output benchmark. item count = {0} start time: {1}", dataList.Count, DateTime.Now.ToLongTimeString()));
        for (int i = 0; i < dataList.Count; i++)
        {

            Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop1", dataList[i].Prop1));
            Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop2", dataList[i].Prop2));
            Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop3", dataList[i].Prop3));
            Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop4", dataList[i].Prop4));
            Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop5", dataList[i].Prop5));
            Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop6", dataList[i].Prop6));
            Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop7", dataList[i].Prop7));
            Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop8", dataList[i].Prop8));
            Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop9", dataList[i].Prop9));
            Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop10", dataList[i].Prop10));
        }
        Debug.WriteLine("");
        Debug.WriteLine(string.Format(" End direct output benchmark. item count = {0} end time: {1}", dataList.Count, DateTime.Now.ToLongTimeString()));
    }
+5
source share
3 answers

, , :

Debug:

  • . = 1,000,000 : 0.278
  • . = 1,000,000 : 5.622
  • . = 1 000 000 : 0.045

Release:

  • . = 1,000,000 : 0.194
  • . = 1 000 000 : 5.523
  • . = 1 000 000 : 0.003

, , ?

class ReflectClass1
{
    public ReflectClass1(Random rand)
    {
        Prop1 = rand.Next();
        Prop2 = rand.Next();
        Prop3 = rand.Next();
        Prop4 = rand.Next();
        Prop5 = rand.Next();
        Prop6 = rand.Next();
        Prop7 = rand.Next();
        Prop8 = rand.Next();
        Prop9 = rand.Next();
        Prop10 = rand.Next();
    }

    public int Prop1 {get;set;}
    public int Prop2 { get; set; }
    public int Prop3 { get; set; }
    public int Prop4 { get; set; }
    public int Prop5 { get; set; }
    public int Prop6 { get; set; }
    public int Prop7 { get; set; }
    public int Prop8 { get; set; }
    public int Prop9 { get; set; }
    public int Prop10 { get; set; }
}

class Program
{
    private static Random random = new Random((int)DateTime.Now.Ticks);
    private List<Func<ReflectClass1, int>> delegateList = new List<Func<ReflectClass1, int>>();
    private static int Iterations = 1000000;

    private void UseDelegateList()
    {
        //setup delegateList
        foreach (var propertyInfo in typeof(ReflectClass1).GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            Func<ReflectClass1, int> getPropDelegate = (Func<ReflectClass1, int>)Delegate.CreateDelegate(typeof(Func<ReflectClass1, int>), null, propertyInfo.GetGetMethod());
            delegateList.Add(getPropDelegate);
        }

        Stopwatch sw = Stopwatch.StartNew();

        ReflectClass1 testClass = new ReflectClass1(random);
        int total = 0;
        for (int i = 0; i < Iterations; i++)
        {
            foreach (var getProp in delegateList)
            {
                total += getProp(testClass);
            }           
        }

        Console.WriteLine(string.Format(" End delegate performance test. iterations = {0:N0} end time: {1:0.000}", Iterations, sw.ElapsedMilliseconds / 1000.0));
        Console.WriteLine(total);
    }

    private void UseDirectReflection()
    {
        Stopwatch sw = Stopwatch.StartNew();

        int total = 0;
        ReflectClass1 testClass = new ReflectClass1(random);
        for (int i = 0; i < Iterations; i++)
        {
            foreach (PropertyInfo propertyInfo in typeof(ReflectClass1).GetProperties())
            {
                if (propertyInfo == null)
                    continue;

                total += (int)propertyInfo.GetValue(testClass, null);
            }
        }

        Console.WriteLine(string.Format(" End direct reflection performance test. iterations = {0:N0} end time: {1:0.000}", Iterations, sw.ElapsedMilliseconds / 1000.0));
        Console.WriteLine(total);
    }

    private void DirectOutputTest()
    {
        Stopwatch sw = Stopwatch.StartNew();

        int total = 0;
        ReflectClass1 testClass = new ReflectClass1(random);
        for (int i = 0; i < Iterations; i++)
        {
            total += testClass.Prop1;
            total += testClass.Prop2;
            total += testClass.Prop3;
            total += testClass.Prop4;
            total += testClass.Prop5;
            total += testClass.Prop6;
            total += testClass.Prop7;
            total += testClass.Prop8;
            total += testClass.Prop9;
            total += testClass.Prop10;
        }


        Console.WriteLine(string.Format(" End direct output benchmark. iterations = {0:N0} end time: {1:0.000}", Iterations, sw.ElapsedMilliseconds / 1000.0));
        Console.WriteLine(total);
    }

    static void Main(string[] args)
    {
        var test = new Program();

        test.UseDelegateList();
        test.UseDirectReflection();
        test.DirectOutputTest();
    }
}
+3

2 :

  • , .NET , . , Framework v3.5 4.0; Framework v2.0, , , .

  • , , - "" . , , , . - .

, . , - :

public class ReflectionTest
    {
        public int Method1(){return 1;}
        public int Method2() { return 2; }
        public int Method3() { return 3; }
        public int Method4() { return 4; }
        public int Method5() { return 5; }
        public int Method6() { return 6; }
    }

    [Test]
    public void TestStatic()
    {
        for (var i = 1; i <= 100000; i++)
        {
            var reflectTest = new ReflectionTest();
            reflectTest.Method1();
            reflectTest.Method2();
            reflectTest.Method3();
            reflectTest.Method4();
            reflectTest.Method5();
            reflectTest.Method6();
        }
    }

    [Test]
    public void TestReflection()
    {
        var fullName = typeof (ReflectionTest).FullName;
        for (var i = 1; i <= 100000; i++)
        {
            var type = Assembly.GetExecutingAssembly().GetType(fullName, true, true);
            var reflectTest = Activator.CreateInstance(type);
            for (var j = 1; j <= 6; j++)
                type.GetMethod("Method" + j.ToString()).Invoke(reflectTest, null);
        }
    }

, , GetMethod 6 "Method1", "Method2" ..

, , Type, Type, . , , . , ; , Object [], (), .

, , ; , , .NET 4.0 , , .

: : 0,07 100 ., 2.12s. / 30 , . 100 000 , ; Debug.WriteLine , , .

+4

. , , . :

, . - , . . , , . -, .

+3

All Articles