至2023年10月,前兩個項目的主要代碼分別都有8年和6年曆史了。Mapster最近還有修改
FastMapper
https://github.com/FastMapper/FastMapper
TinyMapper
https://github.com/TinyMapper/TinyMapper
Mapster
https://github.com/MapsterMapper/Mapster/
Mapster應該只支持net6\net7,三者的速度都號稱比AutoMapper快。我好奇他們誰快。於是對比了一下。
在net6下建了命令行程序,主要測試代碼如下
int max = 100000; Type a = typeof(ClassA); Type b = typeof(ClassB); Type c = typeof(ClassC); Type typeListA = typeof(List<ClassA>); Type typeListB = typeof(List<ClassB>); Type typeListC = typeof(List<ClassC>); var objA = new ClassA() { Name = "kevin", Description = "Test", Age = 132, Birthday = DateTime.Now }; var lstA = new List<ClassA>(); lstA.Add(objA); RunTest("TinyMapper", max, () => { TinyMapper.Bind(a, b); TinyMapper.Bind(a, c); }, () => { var to1 = TinyMapper.Map(a, b, objA); var to2 = TinyMapper.Map(a, c, objA); } ); RunTest("FastMapper", max, () => { }, () => { var to1 = FastMapper.TypeAdapter.Adapt(objA, a, b); var to2 = FastMapper.TypeAdapter.Adapt(objA, a, c); });
FastMapper有一個有意思的表現一定數量級以下比較快
執行100000次,TinyMapper用時 167毫秒 執行100000次,FastMapper用時 96毫秒 執行100000次,Mapster...用時 220毫秒 Test List<A>... 執行100000次,TinyMapper用時 96毫秒 執行100000次,FastMapper用時 146毫秒 執行100000次,Mapster...用時 77毫秒
超過一定數值就比較慢了
執行1000000次,TinyMapper用時 304毫秒 執行1000000次,FastMapper用時 747毫秒 執行1000000次,Mapster...用時 520毫秒 Test List<A>... 執行1000000次,TinyMapper用時 514毫秒 執行1000000次,FastMapper用時 1059毫秒 執行1000000次,Mapster...用時 378毫秒
因爲公司有net4的項目需要維護,所以也做了一個net40下的比較。跟net6的速度對比,net4的明顯慢了。因爲Mapster沒有net4所以沒有參與net4的比較。
執行1000000次,TinyMapper用時 418毫秒 執行1000000次,FastMapper用時 915毫秒 Test List<A>... 執行1000000次,TinyMapper用時 791毫秒 執行1000000次,FastMapper用時 1427毫秒
減少數量,看看FastMapper有沒有net6的怪現象
執行100000次,TinyMapper用時 101毫秒 執行100000次,FastMapper用時 104毫秒 Test List<A>... 執行100000次,TinyMapper用時 92毫秒 執行100000次,FastMapper用時 215毫秒
似乎沒有了。其實我覺得這是誤差範圍,偶爾也有FastMapper快幾毫秒的時候。好了,其實幾個都很快了。
但TinyMapper的使用顯然沒有FastMapper方便,改造一下就好了。
public static object Adapt(Type sourceType, Type targetType, object source, object target = null) { TypePair typePair = TypePair.Create(sourceType, targetType); Mapper mapper = GetOrBuildMapper(typePair); var result = mapper.Map(source, target); return result; } private static Mapper GetOrBuildMapper(TypePair typePair) { Mapper mapper; lock (_mappersLock) { if (_mappers.TryGetValue(typePair, out mapper) == false) { mapper = _targetMapperBuilder.Build(typePair); _mappers[typePair] = mapper; } } return mapper; }
本文只發布在博客園,未經同意請勿轉載!