Un moyen d'améliorer les Automapper la performance?
Je suis un grand fan de AutoMapper. Je suis maintenant de l'utiliser dans de nombreux projets pour la cartographie des entités entre les différents domaines de modèle de service wcf pour modèle d'affaires.
Après quelques tests de charge (avec VS Profiler) dans un échantillon de site web, j'ai trouvé que AutoMapper est responsable de la hausse de la consommation CPU.
J'ai fait une unité de ce comportement :
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace AutoMapper.Tests
{
[TestClass]
public class UnitTest
{
public class ClassSource
{
public string PropertyA { get; set; }
public int PropertyB { get; set; }
public NestedClassSource PropertyC { get; set; }
}
public class NestedClassSource
{
public string PropertyD { get; set; }
public DateTime PropertyE { get; set; }
public List<int> PropertyF { get; set; }
}
public class ClassDestination
{
public string PropertyA { get; set; }
public int PropertyB { get; set; }
public NestedClassDestination PropertyC { get; set; }
}
public class NestedClassDestination
{
public string PropertyD { get; set; }
public DateTime PropertyE { get; set; }
public List<int> PropertyF { get; set; }
}
[TestMethod]
public void MappingPerfTests()
{
Mapper.Initialize(a =>
{
a.CreateMap<ClassSource, ClassDestination>();
a.CreateMap<NestedClassSource, NestedClassDestination>();
});
Mapper.AssertConfigurationIsValid();
IList<ClassSource> items = GenerateRandomSources(nbItems: 500);
//automapper
MicroBench(() =>
{
var res = Mapper.Map<IList<ClassSource>, IList<ClassDestination>>(items);
}, nbIterations: 10);
//will take nearly 30 ms per test
//total : 300 ms
//manual mapper
MicroBench(() =>
{
var res = new List<ClassDestination>(items.Count);
foreach (var source in items)
{
res.Add(new ClassDestination()
{
PropertyA = source.PropertyA,
PropertyB = source.PropertyB,
PropertyC = new NestedClassDestination()
{
PropertyD = source.PropertyC.PropertyD,
PropertyE = source.PropertyC.PropertyE,
PropertyF = new List<int>(source.PropertyC.PropertyF)
}
});
}
}, nbIterations: 10);
//will take nearly 0 ms per test
//total : 1 ms
}
private IList<ClassSource> GenerateRandomSources(int nbItems = 1000)
{
IList<ClassSource> res = new List<ClassSource>(100);
foreach (var i in Enumerable.Range(1, nbItems))
{
ClassSource item = new ClassSource()
{
PropertyA = "PropertyA",
PropertyB = i,
PropertyC = new NestedClassSource() { PropertyD = "PropertyD", PropertyE = DateTime.Now, PropertyF = Enumerable.Range(1, 10).ToList() }
};
res.Add(item);
}
return res;
}
private void MicroBench(Action action, int nbIterations = 1000)
{
long totalElapsed = 0L;
foreach (var i in Enumerable.Range(1, nbIterations))
{
Stopwatch watcher = Stopwatch.StartNew();
action();
watcher.Stop();
Console.WriteLine("test : {0} ms", watcher.ElapsedMilliseconds);
totalElapsed += watcher.ElapsedMilliseconds;
}
Console.WriteLine("total : {0} ms", totalElapsed);
Console.WriteLine("avg : {0} ms", totalElapsed / nbIterations);
}
}
}
À la fin, AutoMapper semble assez lent : en moyenne 30 ms par test alors que le manuel de la cartographie prend moins d'une milliseconde. Je suis "seulement" cartographie 500 "simples" objets ! Peut-être pour un MVC ViewModel, cela se produit rarement, mais d'autres mappage il peut être fréquent.
30 ms semble être rapide, mais le vrai problème, c'est que ce 30 ms (pour rien) est temps CPU sur le serveur web Comment le serveur va traiter une charge lourde (100 utilisateurs simultanés) ? Pas bien en fait, c'est pourquoi notre test de charge, lance un avertissement.
J'ai fondé une façon de produire de l'expression linq avec Mappeur.CreateMapExpression, mais malheureusement, l'expression ne contient pas les types imbriqués ou des options.
Alors, est-il un moyen d'améliorer les AutoMapper la performance?
Existe-il des pratiques exemplaires?
Merci,
OriginalL'auteur Cybermaxs | 2012-09-21
Vous devez vous connecter pour publier un commentaire.
Regarder dans cet article pour obtenir quelques renseignements sur les AutoMapper, de ses solutions de rechange ainsi que des mesures de performance. Je pense que ça va vous donner un point de vue plus holistique et vous ne vous préoccupez pas de la performance autant.
Ce qui est plus rapide: AutoMapper, Valuinjector, ou manuel de la cartographie? À ce degré, c'est chacun plus vite?
Mon avis seront semblables, il n'y a pas de bonne réponse à ta question (vous n'avez pas vraiment poser une question dans votre message:) ). Vous l'équilibre entre le temps CPU vs le temps de l'homme (à maintenir), et vous ne pouvez pas comparer les deux. Mais à mon humble avis ce devrait être le facteur décisif, mais il est à vous de savoir quelle approche prendre.
Modifier
Essayez de regarder ici pour voir si vous trouver quelques indices pertinents à votre situation: Nécessité d'accélérer automapper...Il faut 32 secondes 113 objets
Aussi un autre lien (bien qu'à partir de 2009), mais peut-être pertinent encore ...
L'analyse de AutoMapper performance
Merci, espérons que cette aide.
OriginalL'auteur Display Name