一个比 AutoMapper 更快的模型映射的组件 Mapster
下面是官方的性能测试 Demo,感性的也可以去 Github 上下载。
贴出代码目的是如果后期直接从自己的博客中在线看。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using AutoMapper;
using Benchmark.Classes;
using Mapster;
using FastExpressionCompiler;
using System.Linq.Expressions; namespace Benchmark
{
class Program
{
static double sAM;
static double sMP;
static double sMF;
static double sEM; static Func<LambdaExpression, Delegate> defaultCompiler = TypeAdapterConfig.GlobalSettings.Compiler; static void Main(string[] args)
{
try
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Foo, Foo>();
cfg.CreateMap<Address, Address>();
cfg.CreateMap<Address, AddressDTO>();
cfg.CreateMap<Customer, CustomerDTO>();
});
TestSimpleTypes();
TestComplexTypes(); Console.WriteLine();
Console.WriteLine($"======================================================================================");
Console.WriteLine($"| Tests | Time (ms) | Slower than Mapster | Slower than Mapster + FEC |");
Console.WriteLine($"======================================================================================");
Console.WriteLine($"| Mapster v3.1.8 | { sMP,9} | { sMP / sMP,18:N2}X | { sMP / sMF,24:N2}X |");
Console.WriteLine($"| Mapster v3.1.8 + FEC | { sMF,9} | { sMF / sMP,18:N2}X | { sMF / sMF,24:N2}X |");
Console.WriteLine($"| Automapper v7.0.1 | { sAM,9} | { sAM / sMP,18:N2}X | { sAM / sMF,24:N2}X |");
Console.WriteLine($"| ExpressMapper v1.9.1 | { sEM,9} | { sEM / sMP,18:N2}X | { sEM / sMF,24:N2}X |");
Console.WriteLine($"======================================================================================");
Console.WriteLine();
} finally
{
Console.WriteLine("Finish");
Console.ReadLine();
}
} static void TestSimpleTypes()
{
Console.WriteLine("Test 1 : Simple Types");
Console.WriteLine("Competitors : Mapster, ExpressMapper, AutoMapper"); var foo = GetFoo(); TestSimple(foo, ); TestSimple(foo, ); TestSimple(foo, ); TestSimple(foo, ); //Console.WriteLine();
//Console.WriteLine("Automapper to Mapster ratio: " + (AutomapperTime / MapsterTime).ToString("###.00") + " X slower");
//Console.WriteLine("ExpressMapper to Mapster ratio: " + (ExpressMapperTime / MapsterTime).ToString("###.00") + " X slower");
//Console.WriteLine(); } static void TestComplexTypes()
{
Console.WriteLine();
Console.WriteLine(); Console.WriteLine("Test 2 : Complex Types");
Console.WriteLine("Competitors : Mapster, ExpressMapper, AutoMapper"); var customer = GetCustomer(); //TypeAdapterConfig.GlobalSettings.DestinationTransforms.Upsert<Guid>(x => x); //ObjectMapperManager.DefaultInstance.GetMapper<Customer, CustomerDTO>().Map(customer); Test(customer, ); Test(customer, ); Test(customer, ); Test(customer, ); Test(customer, ); //Console.WriteLine();
//Console.WriteLine("Automapper to Mapster ratio: " + (AutomapperTime/MapsterTime).ToString("###.00") + " X slower");
//Console.WriteLine("ExpressMapper to Mapster ratio: " + (ExpressMapperTime/MapsterTime).ToString("###.00") + " X slower");
//Console.WriteLine();
} static void Test(Customer item, int iterations)
{
Console.WriteLine(); Console.WriteLine("Iterations : {0}", iterations); //TestCustomerNative(item, iterations); TypeAdapterConfig.GlobalSettings.Compiler = defaultCompiler; //switch compiler
TypeAdapterConfig.GlobalSettings.Compile(typeof(Customer), typeof(CustomerDTO)); //recompile
item.Adapt<Customer, CustomerDTO>(); //exercise
TestMapsterAdapter<Customer, CustomerDTO>(item, iterations, ref sMP); TypeAdapterConfig.GlobalSettings.Compiler = exp => exp.CompileFast(); //switch compiler
TypeAdapterConfig.GlobalSettings.Compile(typeof(Customer), typeof(CustomerDTO)); //recompile
item.Adapt<Customer, CustomerDTO>(); //exercise
TestMapsterAdapter<Customer, CustomerDTO>(item, iterations, ref sMF); ExpressMapper.Mapper.Map<Customer, CustomerDTO>(item); //exercise
TestExpressMapper<Customer, CustomerDTO>(item, iterations, ref sEM); Mapper.Map<Customer, CustomerDTO>(item); //exercise
TestAutoMapper<Customer, CustomerDTO>(item, iterations, ref sAM);
} static void TestSimple(Foo item, int iterations)
{ Console.WriteLine(); Console.WriteLine("Iterations : {0}", iterations); TypeAdapterConfig.GlobalSettings.Compiler = defaultCompiler; //switch compiler
TypeAdapterConfig.GlobalSettings.Compile(typeof(Foo), typeof(Foo)); //recompile
item.Adapt<Foo, Foo>(); //exercise
TestMapsterAdapter<Foo, Foo>(item, iterations, ref sMP); TypeAdapterConfig.GlobalSettings.Compiler = exp => exp.CompileFast(); //switch compiler
TypeAdapterConfig.GlobalSettings.Compile(typeof(Foo), typeof(Foo)); //recompile
item.Adapt<Foo, Foo>(); //exercise
TestMapsterAdapter<Foo, Foo>(item, iterations, ref sMF); //TestValueInjecter<Foo, Foo>(item, iterations); ExpressMapper.Mapper.Map<Foo, Foo>(item); //exercise
TestExpressMapper<Foo, Foo>(item, iterations, ref sEM); Mapper.Map<Foo, Foo>(item); //exercise
TestAutoMapper<Foo, Foo>(item, iterations, ref sAM);
} static void TestCustomerNative(Customer item, int iterations)
{
Console.WriteLine("Handwritten Mapper:\t" + Loop<Customer>(item, get =>
{
var dto = new CustomerDTO(); dto.Id = get.Id;
dto.Name = get.Name;
dto.AddressCity = get.Address.City; dto.Address = new Address() { Id = get.Address.Id, Street = get.Address.Street, Country = get.Address.Country, City = get.Address.City }; dto.HomeAddress = new AddressDTO() { Id = get.HomeAddress.Id, Country = get.HomeAddress.Country, City = get.HomeAddress.City }; dto.Addresses = new AddressDTO[get.Addresses.Length];
for (int i = ; i < get.Addresses.Length; i++)
{
dto.Addresses[i] = new AddressDTO() { Id = get.Addresses[i].Id, Country = get.Addresses[i].Country, City = get.Addresses[i].City };
} dto.WorkAddresses = new List<AddressDTO>();
foreach (var workAddress in get.WorkAddresses)
{
dto.WorkAddresses.Add(new AddressDTO() { Id = workAddress.Id, Country = workAddress.Country, City = workAddress.City });
} }, iterations));
} static void TestMapsterAdapter<TSrc, TDest>(TSrc item, int iterations, ref double counter)
where TSrc : class
where TDest : class, new()
{
var time = Loop(item, get => get.Adapt<TSrc, TDest>(), iterations);
Console.WriteLine("Mapster:\t\t" + time);
counter += time;
} static void TestExpressMapper<TSrc, TDest>(TSrc item, int iterations, ref double counter)
where TSrc : class
where TDest : class, new()
{
var time = Loop(item, get => ExpressMapper.Mapper.Map<TSrc, TDest>(get), iterations);
Console.WriteLine("ExpressMapper:\t\t" + time);
counter += time;
} static void TestAutoMapper<TSrc, TDest>(TSrc item, int iterations, ref double counter)
where TSrc : class
where TDest : class, new()
{
//if (iterations > 50000)
// Console.WriteLine("AutoMapper still working please wait..."); var time = Loop(item, get => Mapper.Map<TSrc, TDest>(get), iterations);
Console.WriteLine("AutoMapper:\t\t" + time);
counter += time;
} static long Loop<T>(T item, Action<T> action, int iterations = )
{
return Time(item, a =>
{
for (int i = ; i < iterations; i++)
{
action(a);
}
});
} static long Time<T>(T item, Action<T> action)
{
var sw = new Stopwatch();
sw.Start();
action(item);
sw.Stop();
return sw.ElapsedMilliseconds;
} #region Data static Customer GetCustomer()
{
Customer c = new Customer()
{
Address = new Address() { City = "istanbul", Country = "turkey", Id = , Street = "istiklal cad." },
HomeAddress = new Address() { City = "istanbul", Country = "turkey", Id = , Street = "istiklal cad." },
Id = ,
Name = "Eduardo Najera",
Credit = 234.7m,
WorkAddresses = new List<Address>()
{
new Address() {City = "istanbul", Country = "turkey", Id = , Street = "istiklal cad."},
new Address() {City = "izmir", Country = "turkey", Id = , Street = "konak"}
},
Addresses = new List<Address>()
{
new Address() {City = "istanbul", Country = "turkey", Id = , Street = "istiklal cad."},
new Address() {City = "izmir", Country = "turkey", Id = , Street = "konak"}
}.ToArray()
}; return c;
} static Foo GetFoo()
{
var o = new Foo
{
Name = "foo",
Int32 = ,
Int64 = ,
NullInt = ,
DateTime = DateTime.Now,
Doublen = ,
Foo1 = new Foo { Name = "foo one" },
Foos = new List<Foo>
{
new Foo {Name = "j1", Int64 = , NullInt = },
new Foo {Name = "j2", Int32 = , NullInt = },
new Foo {Name = "j3", Int32 = , NullInt = },
},
FooArr = new[]
{
new Foo {Name = "a1"},
new Foo {Name = "a2"},
new Foo {Name = "a3"},
},
IntArr = new[] { , , , , },
Ints = new[] { , , },
}; return o;
} #endregion }
}
谢谢浏览!
一个比 AutoMapper 更快的模型映射的组件 Mapster的更多相关文章
- 一个比NPM更快更安全可靠的JavaScript包管理工具——Yarn
		
yarn安装: npm intall -g yarn 查看安装是否成功: yarn -v yarn常用的命令以及和npm的对照如下: 更详细的请查看官方文档
 - linux 下程序员专用搜索源码用来替代grep的软件ack(后来发现一个更快的: ag), 且有vim插件的
		
发现一个比ack更快更好用的: https://github.com/ggreer/the_silver_searcher , 使用时命令为ag,它是基于ack的代码二次开发的,所有使用方法基本 ...
 - 比NGINX更快:nginx-1.15.5 vs mongols-1.2.3
		
nginx是多进程web服务器的优秀代表. 本文要用mongols-1.2.3实现一个比nginx更快的多进程的web服务器. mongols是C++ 服务器基础设施库, 它的主要特性如下: tcp ...
 - 修复bug有哪些更快的技术?做好这6点就够了
		
你有没有想过为什么有时修复错误似乎比它应该花费更长的时间?当你终于找到问题时,事实证明你所需要的只是一个小小的改变.然而,花了很多时间才能找到正在发生的事情.这种情况比我想象的更频繁. 另一方面,当您 ...
 - MindSpore模型精度调优实战:如何更快定位精度问题
		
摘要:为大家梳理了针对常见精度问题的调试调优指南,将以"MindSpore模型精度调优实战"系列文章的形式分享出来,帮助大家轻松定位精度问题,快速优化模型精度. 本文分享自华为云社 ...
 - EdgeFormer: 向视觉 Transformer 学习,构建一个比 MobileViT 更好更快的卷积网络
		
 前言 本文主要探究了轻量模型的设计.通过使用 Vision Transformer 的优势来改进卷积网络,从而获得更好的性能. 欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结.最新技术跟 ...
 - android开发者您还在为模拟器犯愁吗?神级android模拟器---Genymotion一个更快、接近完美的模拟器……
		
摘要:Android系统非常特别,App须要进行模拟化測试.即使这样仍然有解决的办法---虚拟化技术. 之前的模拟器比方eclipse自带的是非常慢的一种,并且模拟器的版本号并非最新的.开机.能够说差 ...
 - LSM树——LSM 将B+树等结构昂贵的随机IO变的更快,而代价就是读操作要处理大量的索引文件(sstable)而不是一个,另外还是一些IO被合并操作消耗。
		
Basic Compaction 为了保持LSM的读操作相对较快,维护并减少sstable文件的个数是很重要的,所以让我们更深入的看一下合并操作.这个过程有一点儿像一般垃圾回收算法. 当一定数量的ss ...
 - ZeroMQ一个更小、更快、更简单的智能传输层协议
		
这个githube上的教程是非常好的,是个中文翻译,大家直接学这个就行 https://github.com/anjuke/zguide-cn/tree/master/bin 原文地址: https: ...
 
随机推荐
- mysql 优化之 is null ,is not null 索引使用测试
			
关于mysql优化部分,有很多网友说尽量避免使用is null, is not null,select * 等,会导致索引失效,性能降低?那是否一定收到影响呢?真的就不会使用索引了吗? 本文的测试数据 ...
 - SpringCloud的入门学习之Eureka(Eureka的单节点)
			
SpringCloud--->Spring生态体系的微服务架构:https://spring.io/ 官网贴图,如下所示,介绍了微服务的架构体系(话说,英语好读官网,可能很爽吧,没体验过). 1 ...
 - MongoDB系列---集合与文档操作03
			
MongoDB-——Collection 学习大纲: 1.集合操作 2.文档操作 知识回顾: 上一篇我们讲述了如何对MongoDB的权限和用户进行日常的基本操作,来达到我们对数据库的基本安全保障. 一 ...
 - 使用ZeroClipboard操作剪切板
			
一.ZeroClipboard下载地址 点击下载 二.添加js引用 <script src="../Assets/js/jquery-1.8.3.min.js">< ...
 - python基础(25):面向对象三大特性二(多态、封装)
			
1. 多态 1.1 什么是多态 多态指的是一类事物有多种形态. 动物有多种形态:人,狗,猪. import abc class Animal(metaclass=abc.ABCMeta): #同一类事 ...
 - java基础(12):构造方法、this、super
			
1. 构造方法 我们对封装已经有了基本的了解,接下来我们来看一个新的问题,依然以Person为例,由于Person中的属性都被private了,外界无法直接访问属性,必须对外提供相应的set和get方 ...
 - Python【day 15】基本数据类型-int str bool list
			
'''''' ''' 1 python的定义 是一门弱类型的解释性的高级编程语言 这里的高级是相对低级(例如:汇编语言等) 高级编程语言和低级编程语言的区别 1.前者更接近于人的理解--字母组成的语法 ...
 - Python【day 13】内置函数02
			
一.作用域相关-2个 1.locals() 参数是空 返回当前位置作用域的所有变量,返回的是字典 当前位置:函数内,返回局部变量 当前位置:函数外,返回全局变量 2.globals() 参数是空 返回 ...
 - 控件类——Button、UIControlState状态、title及其属性
			
封装: 封装按钮:1.有提示文字 —>UILable 2.并且可以点击 —> UIControl UIButton:是一个按钮(系统已经把UIControl封装好了). 里面可以放文字. ...
 - Android 布局渲染流程与卡顿优化
			
文章内容概要 一.手机界面UI渲染显示流程 二.16ms原则 三.造成卡顿的原因 四.过度绘制介绍.检测工具.如何避免造成过度绘制造成的卡顿 一.手机界面UI渲染显示流程 大家都知道CPU(中央处理器 ...