EF Core 相關的千倍性能之差: AutoMapper ProjectTo VS Mapster ProjectToType

在前兩天遇到 .NET Core 中 EF Core 的異步與同步查詢的百倍性能之差(詳情以前的博文)以後,這兩天又遇到了 AutoMapper ProjectTo<T>Mapster ProjectToType<T> 的千倍性能之差。html

問題是在昨天發現的,使用 AutoMapper ProjectTo<T> + EF Core 從數據庫中獲取20條記錄居然耗時 10s 左右。git

[Information] Executed DbCommand ("9,947"ms) [Parameters=["@__p_3='20'"], CommandType='Text', CommandTimeout='30']"

若是改成獲取10條記錄,耗時須要 5s 左右,從中能夠推測某個緣由形成獲取單條記錄增長了額外的開銷。github

而用一樣的 SQL 語句在 SSMS 中查詢數據庫飛快,能夠排除不是數據庫層面的問題。數據庫

根據前車可鑑,將異步的 ToListAsync() 改成同步的 ToList() ,但問題依舊。app

對於這個奇怪的問題,從 EF Core 層面實在找不到線索,因而將懷疑的目光轉向了 AutoMapper異步

代碼中用到了 AutoMapper 的 ProjectTopost

return await _postQueryRepository
    .GetPostsByStartId(startId)
    .OrderBy(p => p.Id)
    .Take(itemCount)
    .ProjectTo<T>()
    .ToListAsync();

在配置映射時使用了字符串鏈接:性能

conf.CreateMap<BlogPost, BlogPostDto>()
    .ForMember(dto => dto.AuthorUrl, opt => opt.MapFrom(p => "https://www.cnblogs.com/" + p.BlogSite.Application + "/"));

去掉上面的映射配置以後,速度立馬變得飛快,而 Executed DbCommand 執行時間從 9,947ms 飛流直下 2ms ,原來是 AutoMapper 惹的禍!code

[Information] Executed DbCommand ("2"ms) [Parameters=["@__p_3='20'"], CommandType='Text', CommandTimeout='30']"

而一樣的代碼在 .NET Framework 中沒這個問題,看來是 AutoMapperEF Core 相處不融洽。orm

緣由已經找到,那如何解決或避開這個問題呢?這時想到了剛認識不久瞭解很少的新朋友 —— Mapster ,換上對象映射界的新秀 Mapster 試試。

ProjectTo 改成 ProjectToType ,並以下配置映射關係:

TypeAdapterConfig<BlogPost, BlogPostDto>.ForType()
    .Map(dest => dest.AuthorUrl, src => "https://www.cnblogs.com/" + src.BlogSite.Application + "/");

運行後驚喜地發現 Mapster 沒這個問題,屢次運行 Executed DbCommand 都在 10ms 之內,千倍之差,讓人眼前一亮的新秀。

[Information] Executed DbCommand ("2"ms) [Parameters=["@__p_3='20'"], CommandType='Text', CommandTimeout='30']"

在這冬去春來之際,因爲遇到這個問題,也到了咱們辭去 AutoMapper 迎來 Mapster 的時候。

相關文章
相關標籤/搜索