拷贝对象的开源工具类-FastMapper-TinyMapper-Mapster

发布时间 2023-10-20 12:10:20作者: 生命体验之kevin-Y

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

本文只发布在博客园,未经同意请勿转载!