<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      EmitMapper,AutoMapper,NLiteMapper和手工映射性能大比拼

        在大比拼之前先講一個小插曲,我這個人以前比較低調,做了很多好東西僅僅在公司內的朋友圈項目圈內分享,很少在博客園內進行分享,后來在dudu 老大的文章博客園現代化建設——AutoMapper有感便推薦一下OOMapper 組件,于是乎接連寫了幾篇入門性的介紹使用文章:

         在園友Repository 兄的NLiteMapper與EmitMapper性能簡單比較中了解到NLiteMapper與EmitMapper的性能巨大差距,于是乎進行了兩天的性能優化,同時總結了優化過程:一次性能優化最佳實踐。在這里非常感謝Repository 兄的測試,也非常感謝他把OOMapper糾正為NLiteMapper,否則NLiteMapper的性能是非常低下的,同時感謝dudu,感謝博客園給大家一個平臺,在這個平臺使我學到了很多很多......

           不說廢話進入主題。

           準備工作:

      •   軟硬件環境:VS2008,.net3.5, xp 雙核
      •      測試組件(都是最新Release版本):AutoMapper.dll(v2.0), EmitMappe.dll (V1.0),NLite.dll(V1.0)

           性能測試工具:老趙的CodeTimer

           測試接口代碼:

      [Contract]
      public interface IObjectToObjectMapper
      {
      //初始化映射器
      void Initialize();
      //執行映射
      void Map();
      }

           為了輸出更友好的結果定義一下測試元數據代碼:

      //測試映射器元數據
      public interface IMapperMetadata
      {
      //目錄
      string Category { get; }
      //名稱
      string Name { get; }
      string Descrption { get; }
      }

      //映射器元數據注解
      [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
      [MetadataAttributeAttribute]
      public class MapperAttribute : ComponentAttribute
      {
      public string Category { get; set; }
      public string Name { get; set; }
      public string Descrption { get; set; }
      }

         利用NLite的Mini容器書寫測試框架代碼如下:測試次數10萬次

      class Program
      {
      [InjectMany]
      private Lazy<IObjectToObjectMapper,IMapperMetadata>[] Mappers;

      //初始化映射器,并做一次映射操作
      void Init()
      {
      foreach (var item in Mappers)
      {
      item.Value.Initialize();
      item.Value.Map();
      }

      }

      //進行測試
      void Run()
      {
      foreach (var item in Mappers)
      CodeTimer.Time(item.Metadata.Category
      +"->" + item.Metadata.Name , 100000,() => item.Value.Map());
      }

      static void Main(string[] args)
      {
      ServiceRegistry.RegisteryFromAssemblyOf
      <Program>();

      var host
      = new Program();
      ServiceRegistry.Compose(host);

      host.Init();
      host.Run();

      Console.Read();
      }
      }

      這樣完成了測試框架的搭建,現在就開始書寫測試代碼了。

        定義測試數據:

      public class ModelObject
      {
      public DateTime BaseDate { get; set; }
      public ModelSubObject Sub { get; set; }
      public ModelSubObject Sub2 { get; set; }
      public ModelSubObject SubWithExtraName { get; set; }
      }

      public class ModelSubObject
      {
      public string ProperName { get; set; }
      public ModelSubSubObject SubSub { get; set; }
      }

      public class ModelSubSubObject
      {
      public string IAmACoolProperty { get; set; }
      }

      public class ModelDto
      {
      public DateTime BaseDate { get; set; }
      public string SubProperName { get; set; }
      public string Sub2ProperName { get; set; }
      public string SubWithExtraNameProperName { get; set; }
      public string SubSubSubIAmACoolProperty { get; set; }
      }

          定義測試基類:

      public abstract class MapperBase : IObjectToObjectMapper
      {
      protected ModelObject _source;
      protected ModelDto _target;

      protected virtual void OnInitialize() { }
      public void Initialize()
      {
      OnInitialize();

      _source
      = new ModelObject
      {
      BaseDate
      = new DateTime(2007, 4, 5),
      Sub
      = new ModelSubObject
      {
      ProperName
      = "Some name",
      SubSub
      = new ModelSubSubObject
      {
      IAmACoolProperty
      = "Cool daddy-o"
      }
      },
      Sub2
      = new ModelSubObject
      {
      ProperName
      = "Sub 2 name"
      },
      SubWithExtraName
      = new ModelSubObject
      {
      ProperName
      = "Some other name"
      },
      };
      }

      public abstract void Map();
      }

             手工映射代碼:

      [Mapper(Category = "Flattening.Class", Name = "Manual")]
      public class ManualMapper : MapperBase
      {
      public override void Map()
      {
      var destination
      = new ModelDto
      {
      BaseDate
      = _source.BaseDate,
      Sub2ProperName
      = _source.Sub2.ProperName,
      SubProperName
      = _source.Sub.ProperName,
      SubSubSubIAmACoolProperty
      = _source.Sub.SubSub.IAmACoolProperty,
      SubWithExtraNameProperName
      = _source.SubWithExtraName.ProperName
      };
      }
      }

            AutoMapper 映射代碼:

      [Mapper(Category = "Flattening.Class", Name = "AutoMapper")]
      public class AutoMapperWrapper : MapperBase
      {
      protected override void OnInitialize()
      {
      AutoMapper.Mapper.Initialize(cfg
      =>
      {
      cfg.CreateMap
      <ModelObject, ModelDto>();
      });
      AutoMapper.Mapper.AssertConfigurationIsValid();
      }

      public override void Map()
      {
      _target
      =AutoMapper.Mapper.Map<ModelObject, ModelDto>(_source);
      }
      }

            EmitMapper映射代碼:

      [Mapper(Category = "Flattening.Class", Name = "EmitMapper")]
      public class EmitMapperWrapper : MapperBase
      {
      ObjectsMapper
      <ModelObject, ModelDto> mapper;
      protected override void OnInitialize()
      {
      mapper
      = ObjectMapperManager.DefaultInstance.GetMapper<ModelObject, ModelDto>(new FlatteringConfig());
      }

      protected override ModelDto MapImp()
      {
      return mapper.Map(Source);
      }
      }

       EmitMapper映射器默認不支持Flatter 映射,如果支持需要寫自定義配置:

      class FlatteringConfig : DefaultMapConfig
              {
                  protected Func<string, string, bool> nestedMembersMatcher;
      
                  public FlatteringConfig()
                  {
                      nestedMembersMatcher = (m1, m2) => m1.StartsWith(m2);
                  }
      
                  public override IMappingOperation[] GetMappingOperations(Type from, Type to)
                  {
                      var destinationMembers = GetDestinationMemebers(to);
                      var sourceMembers = GetSourceMemebers(from);
                      var result = new List<IMappingOperation>();
                      foreach (var dest in destinationMembers)
                      {
                          var matchedChain = GetMatchedChain(dest.Name, sourceMembers).ToArray();
                          if (matchedChain == null || matchedChain.Length == 0)
                          {
                              continue;
                          }
                          result.Add(
                              new ReadWriteSimple
                              {
                                  Source = new MemberDescriptor(matchedChain),
                                  Destination = new MemberDescriptor(new[] { dest })
                              }
                          );
                      }
                      return result.ToArray();
                  }
      
                  public DefaultMapConfig MatchNestedMembers(Func<string, string, bool> nestedMembersMatcher)
                  {
                      this.nestedMembersMatcher = nestedMembersMatcher;
                      return this;
                  }
      
                  private List<MemberInfo> GetMatchedChain(string destName, List<MemberInfo> sourceMembers)
                  {
                      var matches = sourceMembers.Where(s => MatchMembers(destName, s.Name) || nestedMembersMatcher(destName, s.Name));
                      int len = 0;
                      MemberInfo match = null;
                      foreach (var m in matches)
                      {
                          if (m.Name.Length > len)
                          {
                              len = m.Name.Length;
                              match = m;
                          }
                      }
                      if (match == null)
                      {
                          return null;
                      }
                      var result = new List<MemberInfo> { match };
                      if (!MatchMembers(destName, match.Name))
                      {
                          result.AddRange(
                              GetMatchedChain(destName.Substring(match.Name.Length), GetDestinationMemebers(match))
                          );
                      }
                      return result;
                  }
      
                  private static List<MemberInfo> GetSourceMemebers(Type t)
                  {
                      return GetMemebers(t)
                          .Where(
                              m =>
                                  m.MemberType == MemberTypes.Field ||
                                  m.MemberType == MemberTypes.Property ||
                                  m.MemberType == MemberTypes.Method
                          )
                          .ToList();
                  }
      
                  private static List<MemberInfo> GetDestinationMemebers(MemberInfo mi)
                  {
                      Type t;
                      if (mi.MemberType == MemberTypes.Field)
                      {
                          t = mi.DeclaringType.GetField(mi.Name).FieldType;
                      }
                      else
                      {
                          t = mi.DeclaringType.GetProperty(mi.Name).PropertyType;
                      }
                      return GetDestinationMemebers(t);
                  }
      
                  private static List<MemberInfo> GetDestinationMemebers(Type t)
                  {
                      return GetMemebers(t).Where(m => m.MemberType == MemberTypes.Field || m.MemberType == MemberTypes.Property).ToList();
                  }
      
                  private static List<MemberInfo> GetMemebers(Type t)
                  {
                      BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public;
                      return t.GetMembers(bindingFlags).ToList();
                  }
              }
      

                NLiteMapper映射代碼:

      [Mapper(Category = "Flattening.Class", Name = "NLiteMapper")]
      public class NLiteMaperWrapper : MapperBase
      {
      private NLite.Mapping.IMapper<ModelObject, ModelDto> mapper;
      protected override void OnInitialize()
      {
      base.OnInitialize();

      mapper
      = NLite.Mapper.CreateMapper<ModelObject, ModelDto>();
      }

      public override void Map()
      {
      _target
      = mapper.Map(_source);
      }
      }

         Ok,完成代碼用Release編譯,然后再輸出bin中找到exe文件,連續執行三次,下面是三次執行結果的截圖:

      ------ Test started: Assembly: NLite.Test.dll ------
      
      Flattening.Class->AutoMapper
      	Time Elapsed:	1,112ms
      	CPU Cycles:	6,718,750
      	Gen 0: 		173
      	Gen 1: 		1
      	Gen 2: 		0
      
      Flattening.Class->NLiteMapper
      	Time Elapsed:	68ms
      	CPU Cycles:	781,250
      	Gen 0: 		4
      	Gen 1: 		1
      	Gen 2: 		0
      
      Flattening.Class->EmitMapper
      	Time Elapsed:	23ms
      	CPU Cycles:	156,250
      	Gen 0: 		3
      	Gen 1: 		0
      	Gen 2: 		0
      
      Flattening.Class->Manual
      	Time Elapsed:	8ms
      	CPU Cycles:	0
      	Gen 0: 		3
      	Gen 1: 		1
      	Gen 2: 		0
      

      ------ Test started: Assembly: NLite.Test.dll ------
      
      Flattening.Class->AutoMapper
      	Time Elapsed:	1,701ms
      	CPU Cycles:	10,468,750
      	Gen 0: 		173
      	Gen 1: 		0
      	Gen 2: 		0
      
      Flattening.Class->NLiteMapper
      	Time Elapsed:	69ms
      	CPU Cycles:	781,250
      	Gen 0: 		4
      	Gen 1: 		1
      	Gen 2: 		0
      
      Flattening.Class->EmitMapper
      	Time Elapsed:	22ms
      	CPU Cycles:	0
      	Gen 0: 		3
      	Gen 1: 		0
      	Gen 2: 		0
      
      Flattening.Class->Manual
      	Time Elapsed:	10ms
      	CPU Cycles:	312,500
      	Gen 0: 		3
      	Gen 1: 		1
      	Gen 2: 		0
      
      
      1 passed, 0 failed, 0 skipped, took 2.98 seconds (NUnit 2.5.5).
      

      ------ Test started: Assembly: NLite.Test.dll ------
      
      Flattening.Class->AutoMapper
      	Time Elapsed:	1,205ms
      	CPU Cycles:	10,156,250
      	Gen 0: 		177
      	Gen 1: 		0
      	Gen 2: 		0
      
      Flattening.Class->NLiteMapper
      	Time Elapsed:	66ms
      	CPU Cycles:	781,250
      	Gen 0: 		4
      	Gen 1: 		0
      	Gen 2: 		0
      
      Flattening.Class->EmitMapper
      	Time Elapsed:	18ms
      	CPU Cycles:	312,500
      	Gen 0: 		3
      	Gen 1: 		0
      	Gen 2: 		0
      
      Flattening.Class->Manual
      	Time Elapsed:	9ms
      	CPU Cycles:	0
      	Gen 0: 		3
      	Gen 1: 		0
      	Gen 2: 		0
      
      
      1 passed, 0 failed, 0 skipped, took 2.56 seconds (NUnit 2.5.5).
      

      通過測試結果可以看出:

      •          手工映射速度最快
      •            EmitMapper第二(大約比手工慢了2-6倍,)
      •            NLiteMapper第三(大約比EmitMapper慢了3倍)
      •            最后是AutoMapper(大約比手工慢了200倍)

          內存開銷結果:

      1. 手工映射              Gen 0: 3
      2. EmitMapper         Gen 0:3
      3. NLiteMapper        Gen 0: 4
      4. AutoMapper        Gen 0:173

          總結 :無論從性能和內存EmitMapper都接近于手工,NLiteMapper次之,AutoMapper最后。NLiteMapper,EmitMapper,AutoMapper都是通過Emit的方式進行Get和Set的,為什么性能差別如此之大,設想如果NLiteMapper不進行優化的話(NLiteMapper一直是通過Emit方式進行的),那么NLiteMapper肯定是高高墊背的(NLiteMapper比EmitMapper慢了15000倍)。。。。。。

        這次測試結果不代表整體結果,僅僅代表Class->Class(包括級聯) 的映射性能,歡迎大家對這幾種OO映射器進行性能比較。最后附上整個測試代碼:測試代碼

        備注:EmitMapper的測試代碼修改過,添加了FlatteringConfig class 這樣測試就公平了。

      附上的源代碼是老代碼,最新代碼:http://nlite.codeplex.com/SourceControl/changeset/view/76359#1528885

      posted @ 2011-04-13 12:49  風云  閱讀(12851)  評論(46)    收藏  舉報
      主站蜘蛛池模板: 久久精品伊人狠狠大香网| 亚洲乱女色熟一区二区三区| 欧美午夜成人片在线观看| 欧美xxxxx高潮喷水| 97国产揄拍国产精品人妻| 久久99热成人精品国产| 99久久无色码中文字幕| 亚洲欧美一区二区三区在线| 国产精品毛片在线看不卡| 亚洲av乱码久久亚洲精品| 中文字幕无码免费久久9一区9| 蜜臀av久久国产午夜| 久久精品国产福利亚洲av| 国产精品一区二区蜜臀av| 精品亚洲无人区一区二区| 天堂mv在线mv免费mv香蕉| 成人午夜免费无码视频在线观看| 国产一区二区三区导航| 日本www一道久久久免费| 久久99九九精品久久久久蜜桃| 久热这里只有精品蜜臀av| 国产精品久久香蕉免费播放| 亚洲精品一区二区美女| 在线a人片免费观看| 国产成人久久精品流白浆| 邹平县| 亚洲av色综合久久综合| 亚洲av日韩av永久无码电影| 日日噜噜夜夜狠狠久久蜜桃| 成人午夜福利精品一区二区| 日本福利一区二区精品| 国产精品白丝久久AV网站| 最新精品国偷自产在线美女足| 国产黄色av一区二区三区| 51妺嘿嘿午夜福利| 在线 欧美 中文 亚洲 精品| 四虎成人精品在永久在线| 久久精品国产只有精品96| 国产成人高清亚洲综合| 亚洲欧洲日产国码久在线| 亚洲国产午夜精品理论片在线播放|