博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
各大主流.Net的IOC框架性能测试比较(转)
阅读量:5015 次
发布时间:2019-06-12

本文共 7013 字,大约阅读时间需要 23 分钟。

出处:

在上一篇中,我简单介绍了下,有人希望能有个性能上的测试,考虑到有那么多的IOC框架,而主流的有:Castle Windsor、微软企业库中的Unity、Spring.NET、StructureMap、Ninject等等。本篇文章主要针对这些IOC框架编写测试程序。

 

Autofac下载地址:

Castle Windsor下载地址:

Unity下载地址:

Spring.NET下载地址:

StructureMap下载地址:

Ninject下载地址:

其中,测试程序均采用最新的类库。

 

基础工作

1、程序还是引用的示例作为测试背景。

 

2、编写一个性能计数器,这里我采用老赵写的一个CodeTimer的类,具体介绍见:

使用方式类似于:

int  iteration  =   100   *   1000 ; string  s  =   "" ; 
CodeTimer.Time( " String Concat " , iteration, ()  =>  { s  +=   " a " ; }); 
StringBuilder sb  =   new  StringBuilder(); 
CodeTimer.Time( " StringBuilder " , iteration, ()  =>  { sb.Append( " a " ); });

 

3、编写一个IRunner运行接口:

public   interface  IRunner 
     void  Start(RunType runType); 
}

以及RunnerBase抽象基础运行类:

public   abstract   class  RunnerBase 
     private   int  _iteration  =  Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings[ " Iteration " ]  ??   " 10000 " ); 
     internal   int  Iteration 
    { 
         get  {  return  _iteration; } 
    }
     internal   void  Time(Action action) 
    { 
        CodeTimer.Time(Name, Iteration, action); 
    }
     protected   abstract   string  Name {  get ; } 

这里_iteration表示测试运行次数,通过配置文件来设置值。Time方法通过计数器对action方法进行Iteration次迭代。

 

编写一个RunManager的运行管理器:

public   class  RunManager 
     public   static   void  Start(IRunner runner) 
    { 
        Start(runner, RunType.Transient); 
    }
     public   static   void  Start(IRunner runner, RunType runType) 
    { 
        runner.Start(runType); 
    } 
}

 

在测试中,我采用两种方式的性能比较,一个是单例状态,一个是非单例状态:

///   <summary>  
///  运行状态 
///   </summary>  
public   enum  RunType 
     ///   <summary>  
     ///  单例 
     ///   </summary>  
    Singleton,
     ///   <summary>  
     ///  瞬时 
     ///   </summary>  
    Transient 

好了,现在我的程序只要继承RunnerBase以及IRunnre接口,就可以实现各个IOC框架的初始化装配的工作了。基础工作已经做好。

 

各个IOC框架测试程序

1、Autofac

public   class  AutofacRunner : RunnerBase, IRunner 
     protected   override   string  Name 
    { 
         get  {  return   " Autofac " ; } 
    }
     public   void  Start(RunType runType) 
    { 
        var builder  =   new  ContainerBuilder();
         // if (runType == RunType.Singleton) 
         //     builder.RegisterType<DatabaseManager>().SingleInstance(); 
         // else 
         //     builder.RegisterType<DatabaseManager>(); 
         // builder.RegisterType<SqlDatabase>().As<IDatabase>(); 
         /// /builder.RegisterModule(new ConfigurationSettingsReader("autofac"));
        builder.RegisterType < SqlDatabase > ().As < IDatabase > (); 
         if  (runType  ==  RunType.Singleton) 
            builder.Register(c  =>   new  DatabaseManager(c.Resolve < IDatabase > ())).SingleInstance(); 
         else  
            builder.Register(c  =>   new  DatabaseManager(c.Resolve < IDatabase > ()));  
        var container  =  builder.Build();
        Time(()  =>  
        { 
            var manager  =  container.Resolve < DatabaseManager > (); 
            manager.Search( " SELECT * FROM USER " ); 
        });
        container.Dispose(); 
    } 

 

2、Castle Windsor

public   class  WindsorRunner : RunnerBase, IRunner 
     protected   override   string  Name 
    { 
         get  {  return   " Castle Windsor " ; } 
    }
     public   void  Start(RunType runType) 
    { 
        var container  =   new  WindsorContainer(); 
         if (runType  ==  RunType.Singleton) 
            container.Register(Component.For( typeof (DatabaseManager)).LifeStyle.Singleton); 
         else  
            container.Register(Component.For( typeof (DatabaseManager)).LifeStyle.Transient);
        container.Register(Component.For( typeof (IDatabase)).ImplementedBy( typeof (SqlDatabase)));
        Time(()  =>  
        { 
            var manager  =  container.Resolve < DatabaseManager > (); 
            manager.Search( " SELECT * FROM USER " ); 
        }); 
    } 

 

3、Unity

public   class  UnityRunner : RunnerBase, IRunner 
     protected   override   string  Name 
    { 
         get  {  return   " Unity " ; } 
    }
     public   void  Start(RunType runType) 
    { 
        var container  =   new  UnityContainer(); 
         if (runType  ==  RunType.Singleton) 
            container.RegisterType < DatabaseManager > ( new  ContainerControlledLifetimeManager()); 
         else  
            container.RegisterType < DatabaseManager > ( new  TransientLifetimeManager()); 
        container.RegisterType < IDatabase, SqlDatabase > ();
        Time(()  =>  
            { 
                var manager  =  container.Resolve < DatabaseManager > (); 
                manager.Search( " SELECT * FROM USER " ); 
            }); 
    } 

 

4、Spring.NET

public   class  SpringRunner : RunnerBase, IRunner 
     protected   override   string  Name 
    { 
         get  {  return   " Spring.NET " ; } 
    }
     public   void  Start(RunType runType) 
    { 
         string  databaseManagerName; 
         if  (runType  ==  RunType.Singleton) 
            databaseManagerName  =   " DatabaseManager_Singleton " ; 
         else  
            databaseManagerName  =   " DatabaseManager_Transient " ;
        Time(()  =>  
        { 
            IApplicationContext context  =  ContextRegistry.GetContext(); 
            var manager  =  (DatabaseManager)context.GetObject(databaseManagerName); 
            manager.Search( " SELECT * FROM USER " ); 
        }); 
    } 

 

5、StructureMap

public   class  StructureMapRunner : RunnerBase, IRunner 
     protected   override   string  Name 
    { 
         get  {  return   " StructureMap " ; } 
    }
     public   void  Start(RunType runType) 
    { 
        ObjectFactory.Initialize(container  =>  
        { 
             if  (runType  ==  RunType.Singleton) 
                container.ForRequestedType < DatabaseManager > ().Singleton(); 
             else  
                container.ForRequestedType < DatabaseManager > (); 
            container.ForRequestedType < IDatabase > ().TheDefaultIsConcreteType < SqlDatabase > (); 
        });
        Time(()  =>  
            { 
                var manager  =  ObjectFactory.GetInstance < DatabaseManager > (); 
                manager.Search( " SELECT * FROM USER " ); 
            }); 
    } 

 

6、Ninject

public   class  NinjectRunner : RunnerBase, IRunner 
     protected   override   string  Name 
    { 
         get  {  return   " Ninject " ; } 
    }
     public   void  Start(RunType runType) 
    { 
        IKernel kernel  =   new  StandardKernel( new  MyNinjectModule(runType));
        Time(()  =>  
        { 
            var manager  =  kernel.Get < DatabaseManager > (); 
            manager.Search( " SELECT * FROM USER " ); 
        }); 
    } 

 

客户端测试程序

static   void  Main( string [] args) 
    CodeTimer.Initialize();
    Console.WriteLine( " IOC - Singleton " ); 
     //  Autofac Singleton 
    RunManager.Start( new  AutofacRunner(), RunType.Singleton);        
     //  Castle Windsor 
    RunManager.Start( new  WindsorRunner(), RunType.Singleton); 
     //  Unity 
    RunManager.Start( new  UnityRunner(), RunType.Singleton); 
     //  Spring.NET 
    RunManager.Start( new  SpringRunner(), RunType.Singleton); 
     //  StructureMap 
    RunManager.Start( new  StructureMapRunner(), RunType.Singleton); 
     //  Ninject 
    RunManager.Start( new  NinjectRunner(), RunType.Singleton);
    Console.WriteLine( " =================================== " ); 
    Console.WriteLine( " IOC - Transient " ); 
     //  Autofac Singleton 
    RunManager.Start( new  AutofacRunner(), RunType.Transient); 
     //  Castle Windsor 
    RunManager.Start( new  WindsorRunner(), RunType.Transient); 
     //  Unity 
    RunManager.Start( new  UnityRunner(), RunType.Transient); 
     //  Spring.NET 
    RunManager.Start( new  SpringRunner(), RunType.Transient); 
     //  StructureMap 
    RunManager.Start( new  StructureMapRunner(), RunType.Transient); 
     //  Ninject 
    RunManager.Start( new  NinjectRunner(), RunType.Transient);
    Console.ReadKey(); 

通过修改App.config的Iteration配置值,来设置迭代次数。

< appSettings >  
   < add  key ="Iteration"  value ="100000"   />  
</ appSettings >  

 

运行结果

1、Iteration=1000:

分析:在千数量级时,Autofac,CastleWindsor、StructureMap基本差不多,效率上比其他的要高。

 

2、Iteration=10000:

分析:在万数量级时,Autofac,CastleWindsor,StructureMap基本效率还是差不多,其中StructureMap效率稍稍有些下降;Spring.NET以及Ninject的性能比较低。

 

3、Iteration=100000:

分析:在十万数量级时,CastleWindsor的效率开始下降,而在Transient方面,StructureMap和Autofac基本差不多。

 

4、Iteration=1000000:

分析:在百万数量级时,Autofac和StructureMap两者还是保持比较高的效率,并且在Transient方面,StructureMap已经超过了Autofac。

 

总结:从测试中,可以看出Autofac和StructureMap在性能上面还是体现出比较大的优势,Ninject可以说性能上较低。而Spring.NET不仅仅专注于IOC方面,它还专注于其他方方面面的功能,所以在IOC方面的性能不是太高。另外,微软的Unity中规中矩,性能较为稳定,也是一个不错的选择。另外,可能测试程序会有所偏差,希望大家也能够指出问题!

转载于:https://www.cnblogs.com/smileberry/p/3502117.html

你可能感兴趣的文章
ios app 真机crash报告分析
查看>>
CRC标准以及简记式
查看>>
SEO搜索引擎
查看>>
关于本地使用tomcat部署web应用,浏览器自动跳转为https的问题
查看>>
一、Text To Speech
查看>>
Java读取并下载网络文件
查看>>
github上构建自己的个人网站
查看>>
在word中粘贴的图片为什么显示不完整
查看>>
SQL Server 数据库的鼠标操作
查看>>
net软件工程师求职简历
查看>>
总线置顶[置顶] Linux bus总线
查看>>
nullnullHandling the Results 处理结果
查看>>
SQL SERVER BOOK
查看>>
JS基础回顾,小练习(判断数组,以及函数)
查看>>
多任务——进程
查看>>
WCF:如何将net.tcp协议寄宿到IIS
查看>>
WebAPI HelpPage支持area
查看>>
Path元素
查看>>
php_soap扩展应用
查看>>
第二百三十一节,Bootstrap 介绍
查看>>