zoukankan      html  css  js  c++  java
  • 各大主流.Net的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中规中矩,性能较为稳定,也是一个不错的选择。另外,可能测试程序会有所偏差,希望大家也能够指出问题!

  • 相关阅读:
    POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)
    UVaLive 5031 Graph and Queries (Treap)
    Uva 11996 Jewel Magic (Splay)
    HYSBZ
    POJ 3580 SuperMemo (Splay 区间更新、翻转、循环右移,插入,删除,查询)
    HDU 1890 Robotic Sort (Splay 区间翻转)
    【转】ACM中java的使用
    HDU 4267 A Simple Problem with Integers (树状数组)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4417 Super Mario (树状数组/线段树)
  • 原文地址:https://www.cnblogs.com/lhxsoft/p/5508811.html
Copyright © 2011-2022 走看看