惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
雷峰网
雷峰网
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Spread Privacy
Spread Privacy
H
Hacker News: Front Page
PCI Perspectives
PCI Perspectives
Webroot Blog
Webroot Blog
罗磊的独立博客
H
Heimdal Security Blog
TaoSecurity Blog
TaoSecurity Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
大猫的无限游戏
大猫的无限游戏
月光博客
月光博客
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Google Online Security Blog
Google Online Security Blog
Last Week in AI
Last Week in AI
美团技术团队
Help Net Security
Help Net Security
The Hacker News
The Hacker News
C
Cisco Blogs
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
The Register - Security
The Register - Security
IT之家
IT之家
WordPress大学
WordPress大学
Jina AI
Jina AI
Recent Commits to openclaw:main
Recent Commits to openclaw:main
H
Help Net Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threat Research - Cisco Blogs
P
Proofpoint News Feed
NISL@THU
NISL@THU
爱范儿
爱范儿
The GitHub Blog
The GitHub Blog
Scott Helme
Scott Helme
V
Vulnerabilities – Threatpost
B
Blog
T
Tenable Blog
博客园 - 三生石上(FineUI控件)
T
The Exploit Database - CXSecurity.com
S
Security Affairs
小众软件
小众软件
Hacker News: Ask HN
Hacker News: Ask HN
Security Latest
Security Latest
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
W
WeLiveSecurity
A
Arctic Wolf
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
M
MIT News - Artificial intelligence

博客园 - Leepy

AI应用平台搭建之旅(上) - 框架篇(附:AICon大会阿里国际Agent应用平台分享) 阿里巴巴LangEngine开源了!支撑亿级网关规模的高可用Java原生AI应用开发框架 在mac上安装Go语言初体验 iOS学习系列 - 标签Tag列表的实现 iOS学习系列 - UITableView下拉更新/上提加载的实现 iOS学习系列 - MonoTouch绑定原生Obj-C静态库的实现 iOS学习系列 - 在iOS客户端实现google oauth2登录以及在asp.net服务端上form认证 iOS学习系列 - 利用ASIHTTPRequest实现异步队列 iOS学习系列 - 扩展机制category与associative Wind.js在移动跨平台框架PhoneGap中的异步体验 Mono for Andriod学习与实践(1)— 初体验 阿里技术嘉年华官网上线啦! Silverlight实现对Sql Server Profiler的SQL实时监控 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习) Silverlight 4以下版本模拟鼠标双击事件 利用Nginx+Mono+Fastcgi代替IIS对Asp.Net进行反向代理 Thrift初探:简单实现C#通讯服务程序 对于.Net中C#指针的研究 依赖注入框架Autofac的简单使用
各大主流.Net的IOC框架性能测试比较
Leepy · 2011-07-17 · via 博客园 - Leepy

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

Autofac下载地址:http://code.google.com/p/autofac/

Castle Windsor下载地址:http://sourceforge.net/projects/castleproject/files/Windsor/2.5/Castle.Windsor.2.5.3.zip/download

Unity下载地址:http://entlib.codeplex.com/

Spring.NET下载地址:http://www.springframework.net/

StructureMap下载地址:http://sourceforge.net/projects/structuremap/files/

Ninject下载地址:http://ninject.org/download

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

基础工作

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

2、编写一个性能计数器,这里我采用老赵写的一个CodeTimer的类,具体介绍见:http://www.cnblogs.com/JeffreyZhao/archive/2009/03/10/codetimer.html

使用方式类似于:

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:

image

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

2、Iteration=10000:

image

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

3、Iteration=100000:

image

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

4、Iteration=1000000:

image

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

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

测试程序源代码:IOCPerformanceTest.rar