Dev365

每时每分都有新收获

导航

利用不同方法创建类的性能比较

Posted on 2004-09-27 11:55  红移  阅读(1186)  评论(2编辑  收藏  举报
在设计和实现中,很多地方都用到reflection。用Reflection创建类会在一定程度上造成性能上的损失。但损失有多大?前些日子写了个程序用不同的方法创建类的实例,测试结果如下:
方法/创建次数 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);

        }

    }

}