Recently, in the framework of a configurable system, a large number of reflection methods are used in the code, although the reflection performance is poor in Java, but in the thought that C # is a strongly typed language, calls to classes in the AppDomain should not be much worse.
Today on the MVP site to see someone said the performance of the reflection is very poor, to avoid the use, wrote a simple example test
The test classes are as follows:
Namespace Reflectiontest.test
{
public class Ctester
{
Public Ctester ()
{
A = 10;
}
public void Test1 ()
{
A = (a-0.0001) * 1.0001;
}
Private double A;
Public double Geta () {return A;}
}
}
First we test the construction of the object
The test code is as follows
private void Test1 ()
{
Label1. Text = "";
Label3. Text = "";
DateTime now = DateTime.Now;
for (int i = 0; i <; i++)
{
for (int j = 0; J <, J + +)
{
Ctester atest = new Ctester ();
}
}
TimeSpan Spand = Datetime.now-now;
Label1. Text = "Time Past" + Spand. ToString ();
}
private void Test2 ()
{
Label2. Text = "";
Label4. Text = "";
DateTime now = DateTime.Now;
for (int i = 0; i <; i++)
{
for (int j = 0; J <, J + +)
{
Type thetest = Type.GetType ("ReflectionTest.Test.CTester");
Object theobj = Thetest.invokemember (null, bindingflags.createinstance
, NULL, NULL, NULL);
}
}
TimeSpan Spand = Datetime.now-now;
Label2. Text = "Time Past" + Spand. ToString ();
}
The test results are directly called at about 16ms, while the reflection call is always maintained at about 5s 520ms, the direct efficiency is nearly 350 times times.
The interesting thing about this test is that:
If the Type in test2 is thetest = Type.GetType ("ReflectionTest.Test.CTester");
Move out of the loop, the corresponding run time is reduced to 1s 332 ms, the efficiency difference is about 20 times times.
Next we have tested the member function calls:
Test1:
private void Button1_Click (object sender, EventArgs e)
{
DateTime now = DateTime.Now;
Ctester atest = new Ctester ();
for (int i = 0; i <; i++)
{
for (int j = 0; J <, J + +)
{
Atest.test1 ();
}
}
TimeSpan Spand = Datetime.now-now;
Label1. Text = "Time Past" + Spand. ToString ();
Label3. Text = "value is now" + Atest.geta ();
}
Test2:
private void Button2_Click (object sender, EventArgs e)
{
DateTime now = DateTime.Now;
Type thetest = Type.GetType ("ReflectionTest.Test.CTester");
Object theobj = Thetest.invokemember (null, bindingflags.createinstance
, NULL, NULL, NULL);
for (int i = 0; i <; i++)
{
for (int j = 0; J <, J + +)
{
Thetest.invokemember ("Test1", BindingFlags.InvokeMethod, NULL, theobj, new object[0]);
}
}
Ctester Thewar = theobj as Ctester;
TimeSpan Spand = Datetime.now-now;
Label2. Text = "Time Past" + Spand. ToString ();
Label4. Text = "value is now" + Thewar.geta ();
}
This example only uses the invoke member to test
The preliminary data were as follows:
Test1:10 ms
Test2:2m 53ms
Multiple tests, the resulting data has a slight fluctuation, but the basic ratio is maintained at about 1:250
For static method calls
Results for 5ms-3m 164ms
Using ILDASM to view the declared IL code, it is found that in addition to function calls, the claimed code is basically consistent, and the difference in visible performance is determined by the
callvirt instance Object [Mscorlib]system.type::invokemember (String,
ValueType [Mscorlib]system.reflection.bindingflags,
class [Mscorlib]system.reflection.binder,
Object
Object[])
resulting in a loss of performance due to reflection.
Although only a few simple reflections were tried with InvokeMember, it is clear that the reflection consumption is very large.
Author blog:http://blog.csdn.net/leafwiz/