主流IOC框架测验(.NET)

上一篇中,我简单介绍了下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:

分析:在千数量级时,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中规中矩,性能较为稳定,也是一个不错的选择。另外,可能测试程序会有所偏差,希望大家也能够指出问题!

DEMO源码下载

转自:http://www.cnblogs.com/liping13599168/archive/2011/07/17/2108734.html

时间: 2024-08-29 09:21:17

主流IOC框架测验(.NET)的相关文章

各大主流.Net的IOC框架性能测试比较

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

今天研究Unity Ioc 框架

今天研究Unity Ioc 框架,被自己坑了两个多小时. 运行就报错,反反复复检查了很多次,配置文件,代码都没有问题,也从新写了好几遍. 最后仔细看报错消息才知道,config文件没有生成到目录----  -_- 各路大神,引以为鉴呀!

PHP的高效IOC框架——CanoeDI

PHP的高效IOC框架--CanoeDI 一个非常简单且实用的IoC框架,相对于其他的Ioc框架有如下特点: 高效: 框架使用了非常实用且高效的算法,使得框架本身对应用的影响微乎其微,且框架提供了C扩展,最大限度的将性能提升到最高. 配置简单: 大多数情况下几乎不需要额外的配置 自动装配: 基于PHPDocument的property属性来自动装配 懒加载: 所有被注入的变量的实例都为即用即取, 不会产生内存垃圾 IDE友好: 因为利用的是PHP的标准规范, 兼容大部分IDE 安装 编译安装,可

Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】

1.概述 首先我们来吹吹牛,什么叫IoC,控制反转(Inversion of Control,英文缩写为IoC),什么意思呢? 就是你一个类里面需要用到很多个成员变量,传统的写法,你要用这些成员变量,那么你就new 出来用呗~~ IoC的原则是:NO,我们不要new,这样耦合度太高:你配置个xml文件,里面标明哪个类,里面用了哪些成员变量,等待加载这个类的时候,我帮你注入(new)进去: 这样做有什么好处呢? 回 答这个问题,刚好可以回答另一个问题,很多人问,项目分层开发是吧,分为控制层.业务层

开关控件在主流前端框架中的使用方法

本文仅介绍使用方法,后续再介绍实现方案及优劣对比. jquerymobile jqm可以使用checkbox和select模拟switch控件,只需要增加data-role='flipswitch'即可: 默认开关控件: <input type="checkbox" data-role="flipswitch" /> 若要变为选中状态,只需要增加一个checked属性即可,如下: <input type="checkbox" d

来,咱们自己写一个Android的IOC框架!

到目前位置,afinal开发框架也是用了好几个月了,还记得第一次使用注释完成控件的初始化和事件绑定的时候,当时的心情是多么的兴奋- -代码竟然可以这样写!然后随着不断的学习,也慢慢的对IOC框架和注解反射等东西有了一点简单的了解,之前的一篇文章简单的介绍了一下Java的反射机制,今天的文章,就完成一个简单的,基于IOC的小Demo,让大家慢慢的对IOC有一点简单的了解. 首先,什么是IOC呢? 控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来

序列化战争:主流序列化框架Benchmark

序列化战争:主流序列化框架Benchmark GitHub上有这样一个关于序列化的Benchmark,被好多文章引用.但这个项目考虑到完整性,代码有些复杂.为了个人学习,自己实现了个简单的Benchmark测试类,也算是总结一下当今主流序列化框架的用法. 1.序列化的战争 按照序列化后的数据格式,主流的序列化框架主要可以分为四大类:JSON.二进制.XML.RPC.从更高层次来说,JSON和XML都可以算作是文本类的,而RPC类因为不只是序列化,框架往往还提供了底层RPC以及跨语言代码生成等基础

java轻量级IOC框架Guice

Guice是由Google大牛Bob lee开发的一款绝对轻量级的java IoC容器.其优势在于: 速度快,号称比spring快100倍. 无外部配置(如需要使用外部可以可以选用Guice的扩展包),完全基于annotation特性,支持重构,代码静态检查. 简单,快速,基本没有学习成本. Guice和spring各有所长,Guice更适合与嵌入式或者高性能但项目简单方案,如OSGI容器,spring更适合大型项目组织. 注入方式 在我们谈到IOC框架,首先我们的话题将是构造,属性以及函数注入

几款主流PHP框架的优缺点评比

主要参考的PHP框架包括:CodeIgniter.CakePHP.ZendFramework.Symfony.我对很多框架也没有认真使用,只是简单试用了一下,可能很多看法不成熟或者是错误的,请大家指正,一起成长. CodeIgniter 优点: 1. 配置简单,全部的配置使用PHP脚本来配置,执行效率高:具有基本的路由功能,能够进行一定程度的路由:具有初步的Layout功能,能够制作一定程度的界面外观:数据库层封装的不错,具有基本的MVC功能 2. 快速简洁,代码不多,执行性能高,PHP框架简单