51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1438|回复: 1
打印 上一主题 下一主题

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

[复制链接]
  • TA的每日心情
    郁闷
    前天 09:01
  • 签到天数: 980 天

    连续签到: 5 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2016-10-17 11:42:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    在上一篇中,我简单介绍了下Autofac的使用,有人希望能有个性能上的测试,考虑到有那么多的IOC框架,而主流的有:Castle Windsor、微软企业库中的Unity、Spring.NET、StructureMap、Ninject等等。本篇文章主要针对这些IOC框架编写测试程序。
    Autofac下载地址:http://code.google.com/p/autofac/
    Castle Windsor下载地址:http://sourceforge.net/projects/ ... .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、编写一个性能计数器

    使用方式类似于:
    1. int iteration = 100 * 1000;string s = "";
    2. CodeTimer.Time("String Concat", iteration, () => { s += "a"; });
    3. StringBuilder sb = new StringBuilder();
    4. CodeTimer.Time("StringBuilder", iteration, () => { sb.Append("a"); });
    复制代码
    3、编写一个IRunner运行接口:
    1. public interface IRunner
    2. {
    3.     void Start(RunType runType);
    4. }
    复制代码
    以及RunnerBase抽象基础运行类:
    1. public abstract class RunnerBase
    2. {
    3.     private int _iteration = Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["Iteration"] ?? "10000");
    4.     internal int Iteration
    5.     {
    6.         get { return _iteration; }
    7.     }

    8.     internal void Time(Action action)
    9.     {
    10.         CodeTimer.Time(Name, Iteration, action);
    11.     }

    12.     protected abstract string Name { get; }
    13. }
    复制代码
    这里_iteration表示测试运行次数,通过配置文件来设置值。Time方法通过计数器对action方法进行Iteration次迭代。

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


    1. public class RunManager
    2. {
    3.     public static void Start(IRunner runner)
    4.     {
    5.         Start(runner, RunType.Transient);
    6.     }

    7.     public static void Start(IRunner runner, RunType runType)
    8.     {
    9.         runner.Start(runType);
    10.     }
    11. }
    复制代码
    在测试中,我采用两种方式的性能比较,一个是单例状态,一个是非单例状态:
    1. /// <summary>
    2. /// 运行状态
    3. /// </summary>
    4. public enum RunType
    5. {
    6.     /// <summary>
    7.     /// 单例
    8.     /// </summary>
    9.     Singleton,

    10.     /// <summary>
    11.     /// 瞬时
    12.     /// </summary>
    13.     Transient
    14. }
    复制代码
    好了,现在我的程序只要继承RunnerBase以及IRunnre接口,就可以实现各个IOC框架的初始化装配的工作了。基础工作已经做好。

    各个IOC框架测试程序
    1、Autofac:

    1. public class AutofacRunner : RunnerBase, IRunner
    2. {
    3.     protected override string Name
    4.     {
    5.         get { return "Autofac"; }
    6.     }

    7.     public void Start(RunType runType)
    8.     {
    9.         var builder = new ContainerBuilder();

    10.         //if (runType == RunType.Singleton)
    11.         //    builder.RegisterType<DatabaseManager>().SingleInstance();
    12.         //else
    13.         //    builder.RegisterType<DatabaseManager>();
    14.         //builder.RegisterType<SqlDatabase>().As<IDatabase>();
    15.         ////builder.RegisterModule(new ConfigurationSettingsReader("autofac"));

    16.         builder.RegisterType<SqlDatabase>().As<IDatabase>();
    17.         if (runType == RunType.Singleton)
    18.             builder.Register(c => new DatabaseManager(c.Resolve<IDatabase>())).SingleInstance();
    19.         else
    20.             builder.Register(c => new DatabaseManager(c.Resolve<IDatabase>()));  

    21.         var container = builder.Build();

    22.         Time(() =>
    23.         {
    24.             var manager = container.Resolve<DatabaseManager>();
    25.             manager.Search("SELECT * FROM USER");
    26.         });

    27.         container.Dispose();
    28.     }
    29. }
    复制代码
    2、Castle Windsor:
    1. public class WindsorRunner : RunnerBase, IRunner
    2. {
    3.     protected override string Name
    4.     {
    5.         get { return "Castle Windsor"; }
    6.     }

    7.     public void Start(RunType runType)
    8.     {
    9.         var container = new WindsorContainer();
    10.         if(runType == RunType.Singleton)
    11.             container.Register(Component.For(typeof(DatabaseManager)).LifeStyle.Singleton);
    12.         else
    13.             container.Register(Component.For(typeof(DatabaseManager)).LifeStyle.Transient);

    14.         container.Register(Component.For(typeof(IDatabase)).ImplementedBy(typeof(SqlDatabase)));

    15.         Time(() =>
    16.         {
    17.             var manager = container.Resolve<DatabaseManager>();
    18.             manager.Search("SELECT * FROM USER");
    19.         });
    20.     }
    21. }
    复制代码
    3、Unity:
    1. public class UnityRunner : RunnerBase, IRunner
    2. {
    3.     protected override string Name
    4.     {
    5.         get { return "Unity"; }
    6.     }

    7.     public void Start(RunType runType)
    8.     {
    9.         var container = new UnityContainer();
    10.         if(runType == RunType.Singleton)
    11.             container.RegisterType<DatabaseManager>(new ContainerControlledLifetimeManager());
    12.         else
    13.             container.RegisterType<DatabaseManager>(new TransientLifetimeManager());
    14.         container.RegisterType<IDatabase, SqlDatabase>();

    15.         Time(() =>
    16.             {
    17.                 var manager = container.Resolve<DatabaseManager>();
    18.                 manager.Search("SELECT * FROM USER");
    19.             });
    20.     }
    21. }
    复制代码
    4、Spring.NET:
    1. public class SpringRunner : RunnerBase, IRunner
    2. {
    3.     protected override string Name
    4.     {
    5.         get { return "Spring.NET"; }
    6.     }

    7.     public void Start(RunType runType)
    8.     {
    9.         string databaseManagerName;
    10.         if (runType == RunType.Singleton)
    11.             databaseManagerName = "DatabaseManager_Singleton";
    12.         else
    13.             databaseManagerName = "DatabaseManager_Transient";

    14.         Time(() =>
    15.         {
    16.             IApplicationContext context = ContextRegistry.GetContext();
    17.             var manager = (DatabaseManager)context.GetObject(databaseManagerName);
    18.             manager.Search("SELECT * FROM USER");
    19.         });
    20.     }
    21. }
    复制代码
    5、StructureMap:
    1. public class StructureMapRunner : RunnerBase, IRunner
    2. {
    3.     protected override string Name
    4.     {
    5.         get { return "StructureMap"; }
    6.     }

    7.     public void Start(RunType runType)
    8.     {
    9.         ObjectFactory.Initialize(container =>
    10.         {
    11.             if (runType == RunType.Singleton)
    12.                 container.ForRequestedType<DatabaseManager>().Singleton();
    13.             else
    14.                 container.ForRequestedType<DatabaseManager>();
    15.             container.ForRequestedType<IDatabase>().TheDefaultIsConcreteType<SqlDatabase>();
    16.         });

    17.         Time(() =>
    18.             {
    19.                 var manager = ObjectFactory.GetInstance<DatabaseManager>();
    20.                 manager.Search("SELECT * FROM USER");
    21.             });
    22.     }
    23. }
    复制代码
    6、Ninject:
    1. public class NinjectRunner : RunnerBase, IRunner
    2. {
    3.     protected override string Name
    4.     {
    5.         get { return "Ninject"; }
    6.     }

    7.     public void Start(RunType runType)
    8.     {
    9.         IKernel kernel = new StandardKernel(new MyNinjectModule(runType));

    10.         Time(() =>
    11.         {
    12.             var manager = kernel.Get<DatabaseManager>();
    13.             manager.Search("SELECT * FROM USER");
    14.         });
    15.     }
    16. }
    复制代码
    客户端测试程序
    1. static void Main(string[] args)
    2. {
    3.     CodeTimer.Initialize();

    4.     Console.WriteLine("IOC - Singleton");
    5.     // Autofac Singleton
    6.     RunManager.Start(new AutofacRunner(), RunType.Singleton);        
    7.     // Castle Windsor
    8.     RunManager.Start(new WindsorRunner(), RunType.Singleton);
    9.     // Unity
    10.     RunManager.Start(new UnityRunner(), RunType.Singleton);
    11.     // Spring.NET
    12.     RunManager.Start(new SpringRunner(), RunType.Singleton);
    13.     // StructureMap
    14.     RunManager.Start(new StructureMapRunner(), RunType.Singleton);
    15.     // Ninject
    16.     RunManager.Start(new NinjectRunner(), RunType.Singleton);

    17.     Console.WriteLine("===================================");
    18.     Console.WriteLine("IOC - Transient");
    19.     // Autofac Singleton
    20.     RunManager.Start(new AutofacRunner(), RunType.Transient);
    21.     // Castle Windsor
    22.     RunManager.Start(new WindsorRunner(), RunType.Transient);
    23.     // Unity
    24.     RunManager.Start(new UnityRunner(), RunType.Transient);
    25.     // Spring.NET
    26.     RunManager.Start(new SpringRunner(), RunType.Transient);
    27.     // StructureMap
    28.     RunManager.Start(new StructureMapRunner(), RunType.Transient);
    29.     // Ninject
    30.     RunManager.Start(new NinjectRunner(), RunType.Transient);

    31.     Console.ReadKey();
    32. }
    复制代码
    通过修改App.config的Iteration配置值,来设置迭代次数。
    1. <appSettings>
    2.   <add key="Iteration" value="100000" />
    3. </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中规中矩,性能较为稳定,也是一个不错的选择。另外,可能测试程序会有所偏差,希望大家也能够指出问题!

    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏2
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-7-7 13:30 , Processed in 0.068472 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表