拷貝對象的開源工具類-FastMapper-TinyMapper-Mapster

至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);
});
View Code

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;
}

本文只發布在博客園,未經同意請勿轉載!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章