1

I have defined a mapping to/from my DTO object, the properties on one versus the other match excatly except that the DTO Object has collections defined as ISet and the non DTO object has those collectiond defined as HashSet . I've noticed a significant performance hit mapping from DTO -> Non DTO, vs the other way.

AutoMapper seems to have trouble going from Interface from concrete class, I'm wondering if I'm missing something in a mapping, or configuration somewhere to be more explicit. This paradigm exists across our code base, but for my object in question I can map 2k objects from the DTO in about 8 seconds, and I can map the exact same objects to the DTO in about .1 seconds

class ExampleDTO
{
    public int Id;
    public enum Type;
    public DateTime creationTime;
    public ISet<string> StringThings;
    public ISet<int> IntThings;
    public ISet<double> DoubleThings;
}
class Example
{
    public int Id;
    public enum Type;
    public DateTime creationTime;
    public HashSet<string> StringThings;
    public HashSet<int> IntThings;
    public HashSet<double> DoubleThings;
}

Mapping:

CreateMap<ExampleDTO, Example>();
CreateMap<Example, ExampleDTO>();

We found that upgrading Automapper (to version 6.0.2) would be the way to go in our case. Using the updated AutoMapper and the same objects and mappings listed above we saw the ExampleDTO->Example object mapped in 1.57 seconds, and the reverse case mapped in 1.86 seconds. I'm not overly happy posting an answer that says use the upgrade, so I'll post a few options that gave some modest gains, and if anyone else has an actual answer, I'll gladly mark that one.

I tried creating a mapping for the ISet HashSet and this was about twice as fast as without that specified mapping, I cannot remember exactly what I did here, but I found it on the googles.

The other option I tried, was creating Non Mappable HashSets on the DTO object that simply returned the ISet. This was about 3x faster, but still not close to the performance gained by upgrading.

class ExampleDTO
{
    public int Id;
    public enum Type;
    public DateTime creationTime;
    public ISet<string> StringThings;
    [IgnoreMap]
    public HashSet<string> StringThingsHash
    {
        get
        {
            return StringThings;
        }
    }
    public ISet<int> IntThings;
    [IgnoreMap]
    public HashSet<int> IntThingsHash
    {
        get
        {
            return IntThings;
        }
    }
    public ISet<double> DoubleThings;
    [IgnoreMap]
    public HashSet<double> DoubleThingsHash
    {
        get
        {
            return DoubleThings;
        }
    }

and I used the following mapping

CreateMap<ExampleDTO, Example>()
  .ForMember(dest => dest.StringThings, opts => opts.MapFrom(src => src.StringThingsHash)
  .ForMember(dest => dest.IntThings, opts => opts.MapFrom(src => src.IntThingsHash)
  .ForMember(dest => dest.DoubleThings, opts => opts.MapFrom(src => src.DoubleThingsHash);
CreateMap<Example, ExampleDTO>();
4

1 回答 1

0

我们发现升级 Automapper(到 6.0.2 版)将是我们的解决方案。使用更新后的 AutoMapper 以及上面列出的相同对象和映射,我们看到 ExampleDTO->Example 对象在 1.57 秒内映射,而相反的情况在 1.86 秒内映射。我不太高兴发布一个说使用升级的答案,所以我会发布一些带来一些适度收益的选项,如果其他人有实际答案,我会很乐意标记那个。

我尝试为 ISet HashSet 创建一个映射,这大约是没有指定映射的两倍,我不记得我在这里做了什么,但我在谷歌上找到了它。

我尝试的另一个选项是在仅返回 ISet 的 DTO 对象上创建不可映射的 HashSet。这大约快了 3 倍,但仍不接近升级所获得的性能。

class ExampleDTO
{
    public int Id;
    public enum Type;
    public DateTime creationTime;
    public ISet<string> StringThings;
    [IgnoreMap]
    public HashSet<string> StringThingsHash
    {
        get
        {
            return StringThings;
        }
    }
    public ISet<int> IntThings;
    [IgnoreMap]
    public HashSet<int> IntThingsHash
    {
        get
        {
            return IntThings;
        }
    }
    public ISet<double> DoubleThings;
    [IgnoreMap]
    public HashSet<double> DoubleThingsHash
    {
        get
        {
            return DoubleThings;
        }
    }

我使用了以下映射

CreateMap<ExampleDTO, Example>()
  .ForMember(dest => dest.StringThings, opts => opts.MapFrom(src => src.StringThingsHash)
  .ForMember(dest => dest.IntThings, opts => opts.MapFrom(src => src.IntThingsHash)
  .ForMember(dest => dest.DoubleThings, opts => opts.MapFrom(src => src.DoubleThingsHash);
CreateMap<Example, ExampleDTO>();
于 2017-04-19T01:37:38.993 回答