æ©éèšäºã¿ã€ãã«ã説æããŠãããŸããåœåã®èšç»ã§ã¯ãã·ã³ãã«ã ãçŸå®çãªäŸã䜿çšããŠããªãã¬ã¯ã·ã§ã³ã®äœ¿çšãé«éåããããã®é©åã§ä¿¡é Œã§ããã¢ããã€ã¹ãæäŸããäºå®ã§ãããããã³ãããŒã¯äžã«ããªãã¬ã¯ã·ã§ã³ã¯æã£ãã»ã©é
ããªããæªå€¢ããã LINQ ãé
ãããšãå€æããŸãããããããçµå±ã®ãšãããç§ã寞æ³ãééããŠããããšãå€æããŸãã... ãã®äººçã®ç©èªã®è©³çŽ°ã¯ã«ããã®äžãšã³ã¡ã³ãã«ãããŸãããã®äŸã¯éåžžã«ãããµãããã®ã§ãããååãšããŠäŒæ¥ã§éåžžè¡ãããŠããããã«å®è£
ãããŠããããã人çã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ãšããŠéåžžã«èå³æ·±ããã®ã§ããããšãããããŸãããèšäºã®äž»èŠãªäž»é¡ã®é床ãžã®åœ±é¿ã¯æ¬¡ã®ãšããã§ããå€éšããžã㯠(MoqãAutofacãEF Coreããã®ä»ã®ããã³ãã£ã³ã°ã) ã®ããç®ç«ã¡ãŸããã
ç§ã¯ãã®èšäºãèªãã§æ¬¡ã®ãããªå°è±¡ãåããŠä»äºãå§ããŸããã
ã芧ã®ãšãããäœæè ã¯ãã¢ããªã±ãŒã·ã§ã³ãå€§å¹ ã«é«éåããåªããæ¹æ³ãšããŠããªãã¬ã¯ã·ã§ã³åã¡ãœãããçŽæ¥åŒã³åºãã®ã§ã¯ãªããã³ã³ãã€ã«ãããããªã²ãŒãã䜿çšããããšãææ¡ããŠããŸãããã¡ãããIL ã®æŸåºã¯ãããŸãããããã¯ã¿ã¹ã¯ãå®è¡ããããã®æãåŽåéçŽçãªæ¹æ³ã§ããããšã©ãŒãå€ããããããã¯é¿ããããšèããŠããŸãã
ç§ãåå°ã®éãã«ã€ããŠã¯åžžã«åæ§ã®æèŠãæã£ãŠããããšãèæ ®ãããšãç¹ã«èè ã®çµè«ã«çåãåããã€ããã¯ãããŸããã§ããã
äŒæ¥å ã§ãªãã¬ã¯ã·ã§ã³ãåçŽã«äœ¿çšãããŠããããšã«ããééããŸããåãåãããŠããŸããç©ä»¶ã«é¢ããæ å ±ãååŸããŸãã SetValue ã¡ãœãããåŒã³åºãããå šå¡ãåã³ãŸããç®çã®ãã£ãŒã«ãã«å€ãå°çãã誰ããæºè¶³ããŠããŸããéåžžã«è³¢ã人ãã¡ãã€ãŸãäžçŽè ãããŒã ãªãŒããŒã¯ãããã¿ã€ãããå¥ã®ã¿ã€ããžã®ãã®ãããªåçŽãªå®è£ ã®ããŠãããŒãµã«ãããããŒã«åºã¥ããŠããªããžã§ã¯ããžã®æ¡åŒµæ©èœãäœæããŸããéåžžãæ¬è³ªã¯æ¬¡ã®ãšããã§ãããã¹ãŠã®ãã£ãŒã«ããååŸãããã¹ãŠã®ããããã£ãååŸããŠãããããå埩åŠçããŸããåã¡ã³ããŒã®ååãäžèŽããå Žåã¯ãSetValue ãå®è¡ããŸããå Žåã«ãã£ãŠã¯ãåã® 1 ã€ã§äœããã®ããããã£ãèŠã€ãããªãã£ããšããééãã«ããäŸå€ãçºçããããšããããŸãããããã§ãããã©ãŒãã³ã¹ãåäžãããæ¹æ³ããããŸããè©ŠããŠ/æãŸããŠãã ããã
以åã®ãã·ã³ãã©ã®ããã«åäœãããã«ã€ããŠã®æ å ±ãååã«æããã«ãããŒãµãŒãããããŒãåçºæãã人ã ãèŠãŠããŸãããç§ã¯ãããããåŸç¶ã®ãã«ãã«ãããèšãèš³ã«ãããã®ããã«ãçŽ æŽãªå®è£ ãæŠç¥ã®èåŸãã€ã³ã¿ãŒãã§ãŒã¹ã®èåŸãã€ã³ãžã§ã¯ã·ã§ã³ã®èåŸã«é ã人ã ãèŠãŠããŸãããç§ã¯ãã®ãããªèªèã«éŒ»ã鳎ãããŸãããå®éãç§ã¯å®éã®ããã©ãŒãã³ã¹ ãªãŒã¯ã枬å®ããããã§ã¯ãªããå¯èœã§ããã°ãå®è£ ãå ¥æã§ããã°ããããæé©ãªãå®è£ ã«å€æŽããã ãã§ãããããã£ãŠã以äžã§èª¬æããæåã®æž¬å®å€ã¯ç§ãã²ã©ãæ··ä¹±ãããŸããã
ãªãã¿ãŒãä»ã®ã€ããªãã®ãŒè«è ãèªãã§ããå€ãã®äººã¯ãã³ãŒãå ã®ãªãã¬ã¯ã·ã§ã³ã¯ã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ã«éåžžã«æªåœ±é¿ãäžããçŸè±¡ã§ãããšããå®å šã«å ¬å¹³ãªå£°æã«åºäŒã£ãããšããããšæããŸãã
ãªãã¬ã¯ã·ã§ã³ãåŒã³åºããšãCLR ã¯ã¢ã»ã³ããªãééããŠå¿ èŠãªã¢ã»ã³ããªãèŠã€ããããã¡ã¿ããŒã¿ãååŸãããã解æãããããå¿ èŠããããŸããããã«ãã·ãŒã±ã³ã¹ããã©ããŒã¹ããéã®ãªãã¬ã¯ã·ã§ã³ã«ããã倧éã®ã¡ã¢ãªãå²ãåœãŠãããŸããã¡ã¢ãªã䜿ãæãããŠãããCLR ã GC ãçºèŠããããªãŒãºãå§ãŸããŸããä¿¡ããŠãã ãããããªãé ããªãã¯ãã§ããææ°ã®å®çšŒåãµãŒããŒãã¯ã©ãŠã ãã·ã³ã«å€§éã®ã¡ã¢ãªãæèŒãããŠããŠããåŠçã®å€§å¹ ãªé 延ã¯é¿ããããŸãããå®éãã¡ã¢ãªãå€ãã»ã©ãGC ãã©ã®ããã«åäœãããã«æ°ã¥ãå¯èœæ§ãé«ããªããŸããçè«äžã圌ã«ãšã£ãŠåçã¯äœèšãªéå·Ÿã®ãããªãã®ã§ããã
ãã ããç§ãã¡ã¯ç IoC ã³ã³ãããŒãšæ¥ä»ããããŒã䜿çšããŠããããã®åäœåçããªãã¬ã¯ã·ã§ã³ã«åºã¥ããŠããŸãããéåžžããããã®ããã©ãŒãã³ã¹ã«ã€ããŠçåã¯ãããŸãããããããäŸåé¢ä¿ã®å°å ¥ãšå€éšã®éå®ãããã³ã³ããã¹ã ã¢ãã«ããã®æœè±¡åãéåžžã«å¿ èŠã§ããããããããã«ããŠãããã©ãŒãã³ã¹ãç ç²ã«ããªããã°ãªããªãããã§ã¯ãããŸããããã¹ãŠãã·ã³ãã«ãªã®ã§ãããã©ãŒãã³ã¹ã«ã¯ããŸã圱é¿ããŸããã
å®éããªãã¬ã¯ã·ã§ã³ ãã¯ãããžã«åºã¥ãæãäžè¬çãªãã¬ãŒã ã¯ãŒã¯ã¯ããªãã¬ã¯ã·ã§ã³ ãã¯ãããžãããæé©ã«æäœããããã«ããããçš®é¡ã®ããªãã¯ã䜿çšããŠããŸããéåžžãããã¯ãã£ãã·ã¥ã§ããéåžžããããã¯åŒããªãŒããã³ã³ãã€ã«ãããåŒãšããªã²ãŒãã§ããåããªãŒãããããŒã¯ããªãã¬ã¯ã·ã§ã³ãåŒã³åºããã«åãå¥ã®åã«å€æã§ããé¢æ°ãšåãç §åãã競åèŸæžãç¶æããŸãã
ããã¯ã©ã®ããã«ããŠéæãããã®ã§ãããã?åºæ¬çã«ãããã¯ãã©ãããã©ãŒã èªäœã JIT ã³ãŒããçæããããã«äœ¿çšããããžãã¯ãšäœãå€ãããŸãããã¡ãœãããåããŠåŒã³åºããããšãããã®ã¡ãœããã¯ã³ã³ãã€ã«ãããŸã (ãããŠã確ãã«ããã®ããã»ã¹ã¯é«éã§ã¯ãããŸãã)ããã®åŸã®åŒã³åºãã§ã¯ãå¶åŸ¡ã¯æ¢ã«ã³ã³ãã€ã«ãããã¡ãœããã«ç§»ããããããããã©ãŒãã³ã¹ãå€§å¹ ã«äœäžããããšã¯ãããŸããã
ãã®äŸã§ã¯ãJIT ã³ã³ãã€ã«ã䜿çšããŠãã³ã³ãã€ã«ãããåäœã察å¿ãã AOT ãšåãããã©ãŒãã³ã¹ã§äœ¿çšããããšãã§ããŸãããã®å ŽåãåŒã圹ã«ç«ã¡ãŸãã
åé¡ã®ååã¯æ¬¡ã®ããã«ç°¡åã«å®åŒåã§ããŸãã
ãªãã¬ã¯ã·ã§ã³ã®æçµçµæã¯ãã³ã³ãã€ã«ãããé¢æ°ãå«ãããªã²ãŒããšããŠãã£ãã·ã¥ããå¿
èŠããããŸãããŸããå¿
èŠãªãã¹ãŠã®ãªããžã§ã¯ããããªããžã§ã¯ãã®å€éšã«æ ŒçŽãããŠããå (ã¯ãŒã«ãŒ) ã®ãã£ãŒã«ãã«åæ
å ±ãšãšãã«ãã£ãã·ã¥ããããšãæå³ããããŸãã
ããã«ã¯è«çããããŸããåžžèçã«ã¯ãäœããã³ã³ãã€ã«ããŠãã£ãã·ã¥ã§ããå Žåã¯ããããå®è¡ããå¿ èŠããããŸãã
ä»åŸã®ããšãèãããšãææ¡ãããåŒã®ã³ã³ãã€ã«æ¹æ³ã䜿çšããªãå Žåã§ãããªãã¬ã¯ã·ã§ã³ã䜿çšãããã£ãã·ã¥ã«ã¯å©ç¹ããããšèšããŸããå®éãããã§ã¯ç§ãäžã§åç §ããèšäºã®èè ã®äž»åŒµãç¹°ãè¿ããŠããã ãã§ãã
次ã«ã³ãŒãã«ã€ããŠã§ããæ·±å»ãªä¿¡çšæ©é¢ã®æ¬æ Œçãªå¶äœã§ç§ãçŽé¢ããªããã°ãªããªãã£ãæè¿ã®çã¿ã«åºã¥ããäŸãèŠãŠã¿ãŸãããããã¹ãŠã®ååšã¯æ¶ç©ºã®ãã®ã§ããããã誰ãæšæž¬ã§ããŸããã
ããçšåºŠã®æ¬è³ªã¯ãããé£çµ¡ãå ¥ããŸããããæšæºåãããæ¬æãæã€æåããããããããããŒãµãŒãšãã€ãã¬ãŒã¿ãŒãåãé£çµ¡å ãäœæããŸããæçŽãå°çããç§ãã¡ã¯ãããèªã¿ãããŒãšå€ã®ãã¢ã«è§£æããŠé£çµ¡å ãäœæããããŒã¿ããŒã¹ã«ä¿åããŸããã
åæ©çãªããšã§ããé£çµ¡å ã«æ°åã幎霢ãé£çµ¡å é»è©±çªå·ã®ããããã£ããããšããŸãããã®ããŒã¿ã¯æçŽã§éä¿¡ãããŸãããŸããäŒæ¥ã¯ããšã³ãã£ãã£ã®ããããã£ãã¬ã¿ãŒæ¬æã®ãã¢ã«ãããã³ã°ããããã®æ°ããããŒãè¿ éã«è¿œå ã§ãããµããŒããæ±ããŠããŸãã誰ãããã³ãã¬ãŒãã«ã¿ã€ããã¹ãããå ŽåããŸãã¯ãªãªãŒã¹åã«æ°ãããã©ãŒãããã«é©å¿ããŠæ°ããããŒãããŒãããããã³ã°ãç·æ¥ã«èµ·åããå¿ èŠãããå Žåããã®åŸãæ°ãããããã³ã°çžé¢ãå®äŸ¡ãªããŒã¿ãã£ãã¯ã¹ãšããŠè¿œå ã§ããŸããã€ãŸãã人çã®äžäŸã§ãã
ç§ãã¡ã¯ãã¹ããå®è£ ããäœæããŸããåäœããŸãã
ã³ãŒãã¯æäŸããŸããããœãŒã¹ã¯å€æ°ãããèšäºã®æåŸã«ãããªã³ã¯ãã GitHub ã§å ¥æã§ããŸããããªãã®ã±ãŒã¹ã«åœ±é¿ãäžããããã«ãããããããŒãããèªèã§ããªãã»ã©æ·åãã枬å®ããããšãã§ããŸããé«éã§ãããšæ³å®ããããã€ãã¬ãŒã¿ãŒãšãäœéã§ãããšæ³å®ããããã€ãã¬ãŒã¿ãŒãåºå¥ãã 2 ã€ã®ãã³ãã¬ãŒã ã¡ãœããã®ã³ãŒãã®ã¿ã瀺ããŸãã
ããžãã¯ã¯æ¬¡ã®ãšããã§ãããã³ãã¬ãŒã ã¡ãœããã¯ãåºæ¬çãªããŒãµãŒ ããžãã¯ã«ãã£ãŠçæããããã¢ãåãåããŸãã LINQ ã¬ã€ã€ãŒã¯ããŒãµãŒããã³ãã€ãã¬ãŒã¿ãŒã®åºæ¬ããžãã¯ã§ãããããŒã¿ããŒã¹ ã³ã³ããã¹ãã«ãªã¯ãšã¹ããçºè¡ããããŒãããŒãµãŒããã®ãã¢ãšæ¯èŒããŸã (ãããã®é¢æ°ã«ã¯ãæ¯èŒçšã® LINQ ã䜿çšããªãã³ãŒãããããŸã)ã次ã«ããã¢ã¯ã¡ã€ã³ã®æ°Žåã¡ãœããã«æž¡ããããã¢ã®å€ããšã³ãã£ãã£ã®å¯Ÿå¿ããããããã£ã«èšå®ãããŸãã
ãé«éã (ãã³ãããŒã¯ã§ã¯æ¥é èŸãšããŠãé«éã):
protected override Contact GetContact(PropertyToValueCorrelation[] correlations)
{
var contact = new Contact();
foreach (var setterMapItem in _proprtySettersMap)
{
var correlation = correlations.FirstOrDefault(x => x.PropertyName == setterMapItem.Key);
setterMapItem.Value(contact, correlation?.Value);
}
return contact;
}
ã芧ã®ãšãããã»ãã¿ãŒ ããããã£ãæã€éçã³ã¬ã¯ã·ã§ã³ã䜿çšãããŠããŸããããã¯ãã»ãã¿ãŒ ãšã³ãã£ãã£ãåŒã³åºãã³ã³ãã€ã«ãããã©ã ãã§ãã次ã®ã³ãŒãã«ãã£ãŠäœæãããŸãã
static FastContactHydrator()
{
var type = typeof(Contact);
foreach (var property in type.GetProperties())
{
_proprtySettersMap[property.Name] = GetSetterAction(property);
}
}
private static Action<Contact, string> GetSetterAction(PropertyInfo property)
{
var setterInfo = property.GetSetMethod();
var paramValueOriginal = Expression.Parameter(property.PropertyType, "value");
var paramEntity = Expression.Parameter(typeof(Contact), "entity");
var setterExp = Expression.Call(paramEntity, setterInfo, paramValueOriginal).Reduce();
var lambda = (Expression<Action<Contact, string>>)Expression.Lambda(setterExp, paramEntity, paramValueOriginal);
return lambda.Compile();
}
äžè¬çã«ããã¯æããã§ããããããã£ãèµ°æ»ããã»ãã¿ãŒãåŒã³åºãããããã£ã®ããªã²ãŒããäœæããããããä¿åããŸãããã®åŸãå¿ èŠã«å¿ããŠé»è©±ããããŸãã
ãé ãã (ãã³ãããŒã¯ã§ã¯æ¥é èŸããé ãã):
protected override Contact GetContact(PropertyToValueCorrelation[] correlations)
{
var contact = new Contact();
foreach (var property in _properties)
{
var correlation = correlations.FirstOrDefault(x => x.PropertyName == property.Name);
if (correlation?.Value == null)
continue;
property.SetValue(contact, correlation.Value);
}
return contact;
}
ããã§ã¯ãããã«ããããã£ããã€ãã¹ããSetValue ãçŽæ¥åŒã³åºããŸãã
æ確ã«ãããããããã³åèãšããŠãçžé¢ãã¢ã®å€ããšã³ãã£ã㣠ãã£ãŒã«ãã«çŽæ¥æžã蟌ãåçŽãªã¡ãœãããå®è£ ããŸããããã¬ãã£ãã¯ã¹ â æåã
ããã§ã¯ãBenchmarkDotNet ã䜿çšããŠããã©ãŒãã³ã¹ã調ã¹ãŠã¿ãŸãããããããŠçªç¶... (ãã¿ã㬠- ããã¯æ£ããçµæã§ã¯ãããŸããã詳现ã¯ä»¥äžã«ãããŸã)
ããã§äœãèŠããã§ããããïŒ Fast ãã¬ãã£ãã¯ã¹ãèªãããã«æã€ã¡ãœããã¯ãã»ãšãã©ãã¹ãŠã®ãã¹ã§ Slow ãã¬ãã£ãã¯ã¹ãæã€ã¡ãœãããããé
ãããšãããããŸããããã¯ãäœæ¥ã®å²ãåœãŠãšé床ã®äž¡æ¹ã«åœãŠã¯ãŸããŸããäžæ¹ãå¯èœãªéããããç®çãšãã LINQ ã¡ãœããã䜿çšããçŸãããšã¬ã¬ã³ããªãããã³ã°ã®å®è£
ã¯ãéã«çç£æ§ã倧å¹
ã«äœäžãããŸãããã®éãã«ã¯ç§©åºããããŸãããã¹æ°ãå€ãã£ãŠãåŸåã¯å€ãããŸãããå¯äžã®éãã¯ã¹ã±ãŒã«ã§ãã LINQ ã§ã¯ 4 ïœ 200 åé
ããªããã»ãŒåãèŠæš¡ã§ããå€ãã®ãŽââããçºçããŸãã
UPDATED
ç§ã¯èªåã®ç®ãä¿¡ããŠããŸããã§ããããããã«éèŠãªããšã«ãååã¯ç§ã®ç®ãã³ãŒããä¿¡ããŠããŸããã§ãã -
åãã¹ãã®çµæã¯æ¬¡ã®ãšããã§ãã
çµè«: äŒæ¥ã§ãªãã¬ã¯ã·ã§ã³ã䜿çšããå Žåãç¹ã«ããªãã¯ã«é Œãå¿
èŠã¯ãããŸãããLINQ ã¯çç£æ§ãããå€ãæ¶è²»ããŸãããã ããæé©åãå¿
èŠãªé«è² è·ã¡ãœããã§ã¯ãã€ãã·ã£ã©ã€ã¶ãšããªã²ãŒã ã³ã³ãã€ã©ã®åœ¢åŒã§ãªãã¬ã¯ã·ã§ã³ãä¿åã§ããããã«ãããé«éãããžãã¯ãæäŸãããŸããããããããšã§ããªãã¬ã¯ã·ã§ã³ã®æè»æ§ãšã¢ããªã±ãŒã·ã§ã³ã®é床ã®äž¡æ¹ãç¶æã§ããŸãã
ãã³ãããŒã¯ ã³ãŒãã¯ããããå
¥æã§ããŸãã誰ã§ãç§ã®èšèãå確èªã§ããŸãã
PS: ãã¹ãã®ã³ãŒã㯠IoC ã䜿çšãããã³ãããŒã¯ã§ã¯æ瀺çãªæ§é ã䜿çšããŸããå®éã®ãšãããæçµçãªå®è£ ã§ã¯ãããã©ãŒãã³ã¹ã«åœ±é¿ãåãŒããçµæã«ãã€ãºãå€ããªãå¯èœæ§ã®ããèŠçŽ ããã¹ãŠã«ããããŸããã
PPS: ãŠãŒã¶ãŒã«æè¬ããŸã
PPPS: ã¹ã¿ã€ã«ãšãã¶ã€ã³ã®æ¬è³ªãç解ãã现å¿ã®èªè
ã«æè¬ããŸããç§ã¯çµ±äžæ§ãšå©äŸ¿æ§ãéèŠããŠããŸãããã¬ãŒã³ããŒã·ã§ã³ã®å€äº€çãªéšåã«ã¯å€ãã®èŠæãæ®ãããŠããŸãããç§ã¯æ¹å€ãèæ
®ã«å
¥ããŸãããé£ã³éå
·ããé¡ãããŸãã
åºæïŒ habr.com