在设计和实现中,很多地方都用到reflection。用Reflection创建类会在一定程度上造成性能上的损失。但损失有多大?前些日子写了个程序用不同的方法创建类的实例,测试结果如下:
可以看到用new操作符创建类比用Reflection快将近20倍之多。测试代码如下:
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace ReflectionTest
{
public interface ISmartObj
{
object CreateInstance();
}

class TestClass : ISmartObj
{
static int start = 0;
public TestClass()
{
x = start++;
}
public static TestClass Create()
{
return new TestClass();
}

public int x;
ISmartObj Members
}

class ReflectClass
{
private static Type[] memNoTypes = new Type[0];
private static object[] memNoPara = new object[0];
private static int memMaxTimes = 1000000;
private delegate TestClass CreateSmartObject();

[DllImport("kernel32.dll")]
private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);

[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);

private static long UseNew(ISmartObj paraInterface)
{
object o;
long tempStart, tempEnd;
int i;
QueryPerformanceCounter(out tempStart);
for (i=0;i<memMaxTimes;i++)
o = paraInterface.CreateInstance();
QueryPerformanceCounter(out tempEnd);
return tempEnd - tempStart;
}

private static long UseRefection(Type paraType)
{
object o;
int i;
long tempStart, tempEnd;
QueryPerformanceCounter(out tempStart);
for (i=0;i<memMaxTimes;i++)
o = (TestClass)Activator.CreateInstance(paraType, false);
QueryPerformanceCounter(out tempEnd);
return tempEnd - tempStart;
}

private static long UseMethod(MethodInfo paraInfo)
{
object o;
int i;
long tempStart, tempEnd;
QueryPerformanceCounter(out tempStart);
for (i=0;i<memMaxTimes;i++)
o = paraInfo.Invoke(null,memNoPara);
QueryPerformanceCounter(out tempEnd);
return tempEnd - tempStart;
}

private static long UseDelegate(Delegate paraDelegate)
{
object o;
long tempStart, tempEnd;
int i;
QueryPerformanceCounter(out tempStart);
for (i=0;i<memMaxTimes;i++)
o = (TestClass)paraDelegate.DynamicInvoke(memNoPara);
QueryPerformanceCounter(out tempEnd);
return tempEnd - tempStart;
}

[STAThread]
static void Main(string[] args)
{
Type tempType = typeof(TestClass);
ISmartObj tempInterface = (ISmartObj)(new TestClass());
MethodInfo tempInfo = tempType.GetMethod("Create",memNoTypes);
Delegate tempDelegate= Delegate.CreateDelegate(typeof(CreateSmartObject), tempInfo);
long tempFreq, tempCost;

QueryPerformanceFrequency(out tempFreq);

tempCost = UseNew(tempInterface);
Console.WriteLine("UseNew:{0}",tempCost *1000/tempFreq);

tempCost = UseDelegate(tempDelegate);
Console.WriteLine("UseDel:{0}",tempCost *1000/tempFreq);

tempCost = UseRefection(tempType);
Console.WriteLine("UseRef:{0}",tempCost *1000/tempFreq);

tempCost = UseMethod(tempInfo);
Console.WriteLine("UseFun:{0}",tempCost *1000/tempFreq);

}
}
}
| 方法/创建次数 | 1000 | 10000 | 100000 | 1000000 |
| new 操作符 | 0 | 5 | 45 | 472 |
| delegate | 3 | 25 | 241 | 2811 |
| Reflection | 9 | 92 | 890 | 9615 |
| 友元函数 | 17 | 148 | 1492 | 16091 |
可以看到用new操作符创建类比用Reflection快将近20倍之多。测试代码如下:
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace ReflectionTest
{
public interface ISmartObj
{
object CreateInstance();
}
class TestClass : ISmartObj
{
static int start = 0;
public TestClass()
{
x = start++;
}
public static TestClass Create()
{
return new TestClass();
}
public int x;
ISmartObj Members
}
class ReflectClass
{
private static Type[] memNoTypes = new Type[0];
private static object[] memNoPara = new object[0];
private static int memMaxTimes = 1000000;
private delegate TestClass CreateSmartObject();
[DllImport("kernel32.dll")]
private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);
private static long UseNew(ISmartObj paraInterface)
{
object o;
long tempStart, tempEnd;
int i;
QueryPerformanceCounter(out tempStart);
for (i=0;i<memMaxTimes;i++)
o = paraInterface.CreateInstance();
QueryPerformanceCounter(out tempEnd);
return tempEnd - tempStart;
}
private static long UseRefection(Type paraType)
{
object o;
int i;
long tempStart, tempEnd;
QueryPerformanceCounter(out tempStart);
for (i=0;i<memMaxTimes;i++)
o = (TestClass)Activator.CreateInstance(paraType, false);
QueryPerformanceCounter(out tempEnd);
return tempEnd - tempStart;
}
private static long UseMethod(MethodInfo paraInfo)
{
object o;
int i;
long tempStart, tempEnd;
QueryPerformanceCounter(out tempStart);
for (i=0;i<memMaxTimes;i++)
o = paraInfo.Invoke(null,memNoPara);
QueryPerformanceCounter(out tempEnd);
return tempEnd - tempStart;
}
private static long UseDelegate(Delegate paraDelegate)
{
object o;
long tempStart, tempEnd;
int i;
QueryPerformanceCounter(out tempStart);
for (i=0;i<memMaxTimes;i++)
o = (TestClass)paraDelegate.DynamicInvoke(memNoPara);
QueryPerformanceCounter(out tempEnd);
return tempEnd - tempStart;
}
[STAThread]
static void Main(string[] args)
{
Type tempType = typeof(TestClass);
ISmartObj tempInterface = (ISmartObj)(new TestClass());
MethodInfo tempInfo = tempType.GetMethod("Create",memNoTypes);
Delegate tempDelegate= Delegate.CreateDelegate(typeof(CreateSmartObject), tempInfo);
long tempFreq, tempCost;
QueryPerformanceFrequency(out tempFreq);
tempCost = UseNew(tempInterface);
Console.WriteLine("UseNew:{0}",tempCost *1000/tempFreq);
tempCost = UseDelegate(tempDelegate);
Console.WriteLine("UseDel:{0}",tempCost *1000/tempFreq);
tempCost = UseRefection(tempType);
Console.WriteLine("UseRef:{0}",tempCost *1000/tempFreq);
tempCost = UseMethod(tempInfo);
Console.WriteLine("UseFun:{0}",tempCost *1000/tempFreq);
}
}
}


浙公网安备 33010602011771号