前言: 我們在很多項目場景中使用對象映射工具,那麼使用最多的OOM對象工具也就那幾個。今天所說的EmitMapper 和TinyMapper 兩者的性能都是很高的,相比autoMapper 速度不知道快了多少倍,因為我平時使用的最多EmitMapper,所在業餘時間做了一下測試兩者對比。 測試數據: ...
前言:
我們在很多項目場景中使用對象映射工具,那麼使用最多的OOM對象工具也就那幾個。今天所說的EmitMapper 和TinyMapper 兩者的性能都是很高的,相比autoMapper 速度不知道快了多少倍,因為我平時使用的最多EmitMapper,所在業餘時間做了一下測試兩者對比。
測試數據:10萬條和1000萬條,分手動,TinyMapper,EmitMapper分別進行測試。22次用例結果:平均值:(註autoMapper不參與,因為筆者認為性能暫時無法和以上相比)
SELECT TOP (200) typename, AVG(esTime) AS estimed FROM emitTinyMapperData GROUP BY typename ORDER BY 2
結果顯示:
手動生成 458 TinyMapper 535 EmitMapper 618
數據加大到:1000萬條:
手動生成 458 TinyMapper 525 EmitMapper 593
TestModel數據對象(為了方便看就寫在一起了):
1 namespace YGOP.PayCenter.MapperTest 2 { 3 /// <summary> 4 /// 測試對象 5 /// </summary> 6 public class TestModel 7 { 8 public string modelName { get; set; } 9 } 10 11 /// <summary> 12 /// 測試對象A 13 /// </summary> 14 public class TestModelA: TestModel 15 { 16 public string modelNameA { get; set; } 17 public int age { get; set; } 18 public int sex { get; set; } 19 /// <summary> 20 /// 註意此處 21 /// </summary> 22 public OrderItem orderItem { get; set; } 23 } 24 25 public class TestModelB : TestModel 26 { 27 public string modelNameB { get; set; } 28 29 public long sex { get; set; } 30 public int ageB { get; set; } 31 /// <summary> 32 /// 註意此處 33 /// </summary> 34 public string gender { get; set; } 35 public string bak { get; set; } 36 /// <summary> 37 /// 註意此處 38 /// </summary> 39 public OrderItem2 orderItem2 { get; set; } 40 41 } 42 /// <summary> 43 /// 訂單子對象測試 44 /// </summary> 45 public class OrderItem 46 { 47 public string orderId { get;set;} 48 public string subId { get; set; } 49 50 public int qty { get; set; } 51 public double price { get; set; } 52 public string bak { get; set; } 53 54 public string qq { get; set; } 55 public bool isMem { get; set; } 56 57 } 58 59 /// <summary> 60 /// 訂單子對象測試 61 /// </summary> 62 public class OrderItem2 63 { 64 public string orderId { get; set; } 65 public string itemId { get; set; } 66 67 public string qq { get; set; } 68 public int amount { get; set; } 69 public decimal unitprice { get; set; } 70 71 public bool isMem { get; set; } 72 73 }View Code
測試用例代碼:
0.手動生成對象
1 /// <summary> 2 /// 手工生成對象 3 /// </summary> 4 /// <param name="max"></param> 5 /// <returns></returns> 6 private List<TestModelA> HanderCustomObject(int max= 100000) 7 { 8 List<TestModelA> modelAlist = new List<TestModelA>(); 9 10 11 for (int i = 0; i < max; i++) 12 { 13 modelAlist.Add(new TestModelA() 14 { 15 age = i + 10, 16 modelNameA = "測試a" + i, 17 modelName = "測試a" + i, 18 sex = i, 19 orderItem = new OrderItem() 20 { 21 bak = "132" + i, 22 orderId = "orderId" + DateTime.Now.ToString() + i.ToString(), 23 price = i + new Random().Next(20, 100), 24 qty = i, 25 qq = "252445578" + i, 26 subId = "subId" + i 27 , 28 isMem = i % 2 == 0 29 } 30 }); 31 } 32 33 return modelAlist; 34 35 }View Code
1.給 TinyMapper 做對象的關係映射
1 /// <summary> 2 /// 給 TinyMapper 做對象的關係映射 3 /// </summary> 4 private void InitTinyMapperCustomMapper() 5 { 6 7 TinyMapper.Bind<OrderItem, OrderItem2>(mapconfig2Order => 8 { 9 mapconfig2Order.Bind(a => a.qty, b => b.amount); 10 mapconfig2Order.Bind(a => a.price, b => b.unitprice); 11 mapconfig2Order.Bind(a => a.subId, b => b.itemId); 12 mapconfig2Order.Bind(a => a.bak, b => b.amount); 13 }); 14 15 TinyMapper.Bind<TestModelA, TestModelB>(mapConfig => 16 { 17 mapConfig.Ignore(src => src.modelName); 18 mapConfig.Bind(a => a.age, b => b.ageB); 19 mapConfig.Bind(a => a.sex, b => b.gender); 20 mapConfig.Bind(a => a.modelNameA, b => b.modelNameB); 21 mapConfig.Bind(a => a.orderItem, b => b.orderItem2); 22 }); 23 24 25 26 }View Code
2.給EmitMapper 做對象關係的映射
1 /// <summary> 2 /// 給EmitMapper 做對象關係的映射 3 /// </summary> 4 /// <returns></returns> 5 private IMappingConfigurator InitEmitCustomMapper2() 6 { 7 IMappingConfigurator conf = new DefaultMapConfig().ConvertUsing<TestModelA, TestModelB>( 8 v => new TestModelB() 9 { 10 ageB = v.age, 11 gender = (v.sex % 2 == 0 ? "男" : "女"), 12 modelNameB = v.modelNameA, 13 orderItem2 = new OrderItem2() 14 { 15 amount = v.orderItem.qty, 16 itemId = v.orderItem.subId, 17 unitprice = Convert.ToDecimal(v.orderItem.price), 18 qq = v.orderItem.qq, 19 orderId = v.orderItem.orderId, 20 isMem = v.orderItem.isMem 21 } 22 23 }); 24 25 return conf; 26 }View Code
3.最終的調用
1 private void button1_Click(object sender, EventArgs e) 2 { 3 Stopwatch stopwatch = new Stopwatch(); 4 stopwatch.Start(); 5 6 int max = 100000; 7 var modelAlist = HanderCustomObject(); 8 stopwatch.Stop(); 9 string ok1 = string.Format(max + "次,手動生成 所用時間 :{0} 毫秒", stopwatch.ElapsedMilliseconds); 10 textBox1.AppendText(ok1 + "\r\n"); 11 stopwatch.Start(); 12 InitTinyMapperCustomMapper(); 13 var ss = TinyMapperHelper.Instance.Convert<List<TestModelA>, List<TestModelB>>(modelAlist); 14 stopwatch.Stop(); 15 string ok = string.Format(max + "次,TinyMapper 所用時間 :{0} 毫秒", stopwatch.ElapsedMilliseconds); 16 textBox1.AppendText(ok + "\r\n"); 17 18 //Thread.Sleep(1000); 19 stopwatch.Start(); 20 var conf= InitEmitCustomMapper2(); 21 var ccc = EmitMapperHelper.Instance.Convert<List<TestModelA>, List<TestModelB>>(modelAlist, conf); 22 23 stopwatch.Stop(); 24 string ok2 = string.Format(max + "次,EmitMapper 所用時間 :{0} 毫秒", stopwatch.ElapsedMilliseconds); 25 textBox1.AppendText(ok2 + "\r\n"); 26 27 return; 28 }View Code
使用22次後,結果
1 方式/10萬次採樣 耗時/毫秒 2 手動生成 438 3 TinyMapper 549 4 EmitMapper 681 5 手動生成 428 6 TinyMapper 537 7 EmitMapper 709 8 手動生成 473 9 TinyMapper 534 10 EmitMapper 615 11 手動生成 463 12 TinyMapper 530 13 EmitMapper 617 14 手動生成 486 15 TinyMapper 550 16 EmitMapper 645 17 手動生成 465 18 TinyMapper 551 19 EmitMapper 654 20 手動生成 450 21 TinyMapper 541 22 EmitMapper 641 23 手動生成 442 24 TinyMapper 551 25 EmitMapper 674 26 手動生成 477 27 TinyMapper 543 28 EmitMapper 606 29 手動生成 458 30 TinyMapper 517 31 EmitMapper 584 32 手動生成 445 33 TinyMapper 512 34 EmitMapper 555 35 手動生成 456 36 TinyMapper 521 37 EmitMapper 580 38 手動生成 475 39 TinyMapper 550 40 EmitMapper 613 41 手動生成 523 42 TinyMapper 603 43 EmitMapper 673 44 手動生成 440 45 TinyMapper 500 46 EmitMapper 568 47 手動生成 457 48 TinyMapper 532 49 EmitMapper 607 50 手動生成 410 51 TinyMapper 472 52 EmitMapper 559 53 手動生成 477 54 TinyMapper 536 55 EmitMapper 596 56 手動生成 449 57 TinyMapper 521 58 EmitMapper 595 59 手動生成 488 60 TinyMapper 554 61 EmitMapper 640 62 手動生成 463 63 TinyMapper 520 64 EmitMapper 587 65 手動生成 432 66 TinyMapper 560 67 EmitMapper 605View Code
個人使用總結:
tinyMapper 真的挺快的,EmitMapper 僅比其差了一點點而已(10萬-1000萬條數據中的映射場景並不多見,70多毫秒也不會太在意)。
因為EmitMapper的作者在2011年就不在維護了,我認為EmitMapper還是夠弔的了。
但tinyMapper 剛出來不久,但性能真的是無與倫對的美麗!!贊,希望能作者能改善。
最後給出我心中,以上工具的打分和優點缺點簡單評。