Note
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãµã€ã³ã€ã³ãŸãã¯ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®èšäºã§ã¯ãå€§èŠæš¡ãª .NET Framework ã¢ããªãããã¡ã€ã«ãããŒã¿ããŒã¹ãªã©å€§éã®ããŒã¿ãåŠçããã¢ããªã®ããã©ãŒãã³ã¹æ¹åã®ãã³ãã説æããŸãã 説æãããã³ã㯠C# ããã³ Visual Basic ã³ã³ãã€ã©ã ãããŒãžã ã³ãŒãã§äœæãçŽããéã«åŸããããã®ã§ãããã®èšäºã§ã¯ C# ã³ã³ãã€ã©ã§ã®å®éã®äŸãããã€ã玹ä»ããŸãã
.NET Framework ã¯ãçç£æ§ã®é«ãã¢ããªéçºç°å¢ã§ãã 匷åã§å®å šãªèšèªãšè±å¯ãªã©ã€ãã©ãªã«ãããã¢ããªã®éçºçç£æ§ãé«ããªããŸãã ãã ããé«ãçç£æ§ã«ã¯è²¬ä»»ã䌎ããŸãã .NET Framework ã®ããããæ©èœã䜿çšããããã®ã§ããã°ãå¿ èŠã«å¿ããŠã³ãŒãã®ããã©ãŒãã³ã¹ã調æŽã§ããããã«ããŠããå¿ èŠããããŸãã
æ°ããã³ã³ãã€ã©ã®ããã©ãŒãã³ã¹ãã¢ããªã«é©çšãããçç±
.NET ã³ã³ãã€ã© ãã©ãããã©ãŒã ("Roslyn") ããŒã ã¯ãã³ãŒãã®ã¢ããªã³ã°ãšåæãããŒã«ã®éçºããã㊠Visual Studio ã§ã®ããå å®ããã³ãŒã察å¿ãšã¯ã¹ããªãšã³ã¹ã®å®çŸã®ããã®æ°ã㪠API ãæäŸãããããC# ããã³ Visual Basic ã³ã³ãã€ã©ããããŒãžã ã³ãŒãã§åäœæããŸããã ã³ã³ãã€ã©ã®å šäœçãªæžãçŽããšãæ°ããã³ã³ãã€ã©ã§ã® Visual Studio æ©èœã®æ§ç¯ãéããŠãå€§èŠæš¡ .NET Framework ã¢ããªãã倧éããŒã¿ãåŠçããã¢ããªã«é©çšã§ããæçšãªããã©ãŒãã³ã¹æ å ±ãæããã«ãªããŸããã C# ã³ã³ãã€ã©ã«ã€ããŠã®ãã®ãããªæ å ±ãäŸã掻çšããããã«ãã³ã³ãã€ã©ã«ã€ããŠçè§£ããŠããå¿ èŠã¯ãããŸããã
Visual Studio ã§ã¯ã³ã³ãã€ã© API ã䜿çšããŠããŠãŒã¶ãŒã«äººæ°ã®ãã IntelliSense æ©èœ (èå¥åãšããŒã¯ãŒãã®è²ã¥ããæ§æã®å ¥ååè£äžèЧããšã©ãŒãç€ºãæ³¢ç·ããã©ã¡ãŒã¿ãŒã®ãã³ããã³ãŒãã®åé¡ãã³ãŒãã¢ã¯ã·ã§ã³ãªã©) ãäœæããŸãã Visual Studio ã§ã¯ãéçºè ãã³ãŒããå ¥åãããšãã倿Žãããšãã«ãã®ãã«ãã衚瀺ãããŸããã³ã³ãã€ã©ãã³ãŒãéçºè ã«ããç·šéå 容ãã¢ãã«åããŠããéããVisual Studio ã¯å¿çæ§ãç¶æããå¿ èŠããããŸãã
ãšã³ã ãŠãŒã¶ã¯ã¢ããªãæäœãããšãã«ãã¢ããªãå¿çãããã®ã§ãããšæåŸ ããŸãã å ¥åãŸãã¯ã³ãã³ãã®åŠçããããã¯ãããããšããã£ãŠã¯ãªããŸããã ãã«ãã¯ããã«ãããã¢ãã衚瀺ããããŸããŠãŒã¶ãŒãå ¥åãç¶ãããšãã«ã¯éããå¿ èŠããããŸãã åŠçæéãããã£ãŠãã UI ã¹ã¬ãããããããããåå ã§ã¢ããªã®åäœãé ããªã£ãŠãããšå€æãããå Žåã§ããã¢ããªããã® UI ã¹ã¬ããããããã¯ããªãããã«ããå¿ èŠããããŸãã
Roslyn ã³ã³ãã€ã©ã®è©³çްã«ã€ããŠã¯ãã.NET Compiler Platform SDKããåç §ããŠãã ããã
äºå®ã ãã
ããã©ãŒãã³ã¹ã調æŽããå¿çæ§ã®ãã .NET Framework ã¢ããªãäœæããéã«ã¯ã次ã«èª¬æããäºå®ãèæ ®ããŠãã ããã
äºå® 1: äºæããªãæé©åã¯ãåžžã«æéããããã ãã®äŸ¡å€ããããšã¯éããŸããã
å¿ èŠä»¥äžã«è€éãªã³ãŒããèšè¿°ãããšãä¿å®ããããã°ã现ããªèª¿æŽã«äŒŽãã³ã¹ããçºçããŸãã çµéšè±å¯ãªããã°ã©ãã¯ãã³ãŒãã£ã³ã°ã®åé¡ã®è§£æ±ºæ¹æ³ãçŽèгçã«ææ¡ããããå¹ççãªã³ãŒããèšè¿°ããŸãã ãããã圌ãã¯æã ãã³ãŒããæ©ãŸã£ãŠæé©åããŠããŸãããšããããŸãã ããšãã°ãåçŽãªé åã§ååãªå Žåã«ããã·ã¥ ããŒãã«ã䜿çšããããåã«å€ãåèšç®ãã代ããã«ãã¡ã¢ãª ãªãŒã¯ãçºçããæãã®ããè€éãªãã£ãã·ã¥ã䜿çšãããããŸãã çµéšè±å¯ãªããã°ã©ãã§ãã£ãŠããããã©ãŒãã³ã¹ã確èªãããã¹ãã宿œããåé¡ãããå Žåã«ã¯ã³ãŒããåæããŠãã ããã
äºå® 2: 枬å®ããŠããªãã®ã§ããã°ãããã¯æšæž¬ã§ãã
ãããã¡ã€ã«ãšæž¬å®ã¯åãã€ããŸããã ãããã¡ã€ã«ãããCPU ã®è² è·ãäžéã«ãªã£ãŠãããã©ããããŸãã¯ãã£ã¹ã¯ I/O ã§ãããã¯ãããŠãããã©ãããããããŸãã ãããã¡ã€ã«ã¯ãå²ãåœãŠãã¡ã¢ãªã®ãµã€ãºãšçš®é¡ãã¬ããŒãž ã³ã¬ã¯ã·ã§ã³ (GC) ã®åŠçã« CPU ãé·ãæéãåãããŠããªãã瀺ããŸãã
ã¢ããªã§ã®äž»èŠãªé¡§å®¢ãšã¯ã¹ããªãšã³ã¹ãã·ããªãªã«ã€ããŠããã©ãŒãã³ã¹ã®ç®æšãèšå®ããããã©ãŒãã³ã¹ã枬å®ãããã¹ããäœæããŠãã ããã ãã¹ã倱æã®èª¿æ»ã«ã¯ç§åŠçãªææ³ã䜿çšããŸããã¬ã€ããšãªããããã¡ã€ã«ã䜿çšããŠãã©ã®ãããªåé¡ãçºçããŠããããä»®å®ããå®éšãã³ãŒã倿Žã«ãã£ãŠãã®ä»®å®ãæ€èšŒããŸãã 宿çã«ãã¹ãã宿œããŠãæéã®çµéãšå ±ã«ããŒã¹ã©ã€ã³ ããã©ãŒãã³ã¹æž¬å®ã確ç«ããŸããããã«ãããããã©ãŒãã³ã¹åŸéãåŒãèµ·ãããŠãã倿Žãåãåããããšãã§ããŸãã ããã©ãŒãã³ã¹æž¬å®ãå³å¯ã«å®æœããããšã§ãäžèŠãªã³ãŒãæŽæ°ã«æéããããããšãåé¿ã§ããŸãã
äºå® 3: åªããããŒã«ã«ã¯å€§ããªå¹æããã
åªããããŒã«ã䜿çšããã°ãæã倧ããªããã©ãŒãã³ã¹ã®åé¡ (CPUãã¡ã¢ãªããŸãã¯ãã£ã¹ã¯) ã®è©³çްãè¿ éã«ç¢ºèªãããã®ãããªããã«ããã¯ãåŒãèµ·ãããŠããã³ãŒããç¹å®ã§ããŸãã Microsoft ã§ã¯ãVisual Studio Profiler ã PerfView ãªã©ãããŸããŸãªããã©ãŒãã³ã¹ ããŒã«ãæäŸããŠããŸãã
PerfView ã¯ããã£ã¹ã¯ I/OãGC ã€ãã³ããã¡ã¢ãªãšãã£ãæ·±ãåé¡ã«éäžããã®ã«åœ¹ç«ã€åŒ·åãªããŒã«ã§ãã ããã©ãŒãã³ã¹ã«é¢é£ãã Windows ã€ãã³ã ãã¬ãŒã·ã³ã° (ETW) ã€ãã³ãããã£ããã£ããã¢ããªå¥ãããã»ã¹å¥ãã¹ã¿ãã¯å¥ãããã³ã¹ã¬ããå¥ã«æ å ±ã容æã«ç¢ºèªã§ããŸãã PerfView ã¯ãã¢ããªã«ãã£ãŠå²ãåœãŠãããã¡ã¢ãªã®çš®é¡ãšéããããŠã¡ã¢ãªã®å²ãåœãŠã«ã©ã®é¢æ°ãŸãã¯ã³ãŒã« ã¹ã¿ãã¯ãã©ã®çšåºŠé¢äžããŠããã®ãã瀺ããŸãã 詳现ã«ã€ããŠã¯ãããŒã«ã«ä»å±ããŠãã詳ãããã«ã ãããã¯ããã¢ããããªãåç §ããŠãã ããã
äºå® 4: ãã¹ãŠã¯å²ãåœãŠã§æ±ºãŸã
å¿çæ§ã®é«ã .NET Framework ã¢ããªéçºã®èŠãšãªãã®ã¯ã¢ã«ãŽãªãºã (äŸ: ããã« ãœãŒãã®ä»£ããã«ã¯ã€ã㯠ãœãŒãã䜿çš) ã§ãããšæããããããŸããããããã¯æ£ãããããŸããã å¿çæ§ã®é«ãã¢ããªãéçºããäžã§æãéèŠãªã®ã¯ãã¡ã¢ãªã®å²ãåœãŠã§ããããã¯ç¹ã«ãã¢ããªãéåžžã«å€§èŠæš¡ã§ãã倧éããŒã¿ãåŠçããå Žåã«è©²åœããŸãã
æ°ããã³ã³ãã€ã© API ã®å¿çæ§ã®é«ã IDE æ©èœã®ã»ãšãã©ã®éçºäœæ¥ã«ã¯ãå²ãåœãŠãåé¿ãããã£ãã·ã¥ ã¹ãã©ããžã管çããããšãé¢é£ããŠããŸããã PerfView ãã¬ãŒã¹ãããæ°ãã C# ããã³ Visual Basic ã³ã³ãã€ã©ã®ããã©ãŒãã³ã¹ã¯ã»ãšãã© CPU ãšã¯é¢é£ããŠããªãããšã倿ããŠããŸãã ãããã®ã³ã³ãã€ã©ã¯ãæ°åäžè¡ããæ°çŸäžè¡ã®ã³ãŒãè¡ã®èªã¿åããã¡ã¿ããŒã¿ã®èªã¿åãããŸãã¯çæãããã³ãŒãã®åºåã®æç¹ã§ã¯ I/O ãšé¢é£ããŠããŸãã UI ã¹ã¬ããã®é å»¶ã®åå ã¯ãã»ãŒã¬ããŒãž ã³ã¬ã¯ã·ã§ã³ã«ãããŸãã .NET Framework GC ã¯ãããã©ãŒãã³ã¹ã®ããã«é«åºŠã«èª¿æŽãããŠããããã®åŠçã®ã»ãšãã©ã¯ã¢ã㪠ã³ãŒãã®å®è¡äžã«åæã«å®è¡ãããŸãã ãã ãã1 åã®å²ãåœãŠã«ãã£ãŠè² è·ã®é«ã gen2 ã³ã¬ã¯ã·ã§ã³ãå®è¡ãããããã«ãã£ãŠãã¹ãŠã®ã¹ã¬ããã忢ãããããšããããŸãã
äžè¬çãªå²ãåœãŠãšäŸ
ãã®ã»ã¯ã·ã§ã³ã®äŸãšããŠæç€ºãããåŒã«ã¯ãèŠãã¥ãããå°ããèŠããå²ãåœãŠããããŸãã ãã ãã倧ããªã¢ããªãåŒãããªãã®åæ°ã«ããã£ãŠå®è¡ãããšãæ°çŸã¡ã¬ãã€ããŸãã¯ã®ã¬ãã€ãã®ã¡ã¢ãªãå²ãåœãŠãããããšããããŸãã ããšãã°ãéçºè ã«ãããšãã£ã¿ãŒãžã®å ¥åãã·ãã¥ã¬ãŒã·ã§ã³ãã 1 åéã®ãã¹ããå®è¡ãããšãããã®ã¬ãã€ãåäœã®ã¡ã¢ãªãå²ãåœãŠããããããããã©ãŒãã³ã¹ ããŒã ã¯å ¥åã«é¢ããã·ããªãªã«éç¹ã眮ããŠåãçµã¿ãŸããã
ãã¯ã·ã³ã°
éåžžã¯ã¹ã¿ãã¯ãŸãã¯ããŒã¿æ§é äœå ã«ããå€åããªããžã§ã¯ãã§ã©ããããããšãããã¯ã¹åãçºçããŸãã ã€ãŸããããŒã¿ãä¿æãããªããžã§ã¯ããå²ãåœãŠããã®ãªããžã§ã¯ããæããã€ã³ã¿ãè¿ããŸãã .NET Framework ã§ã¯ãã¡ãœããã®ã·ã°ããã£ãæ ŒçŽå Žæã®çš®é¡ãåå ã§ãå€ãããã¯ã¹åãããããšããããŸãã ãªããžã§ã¯ãå ã§å€åãã©ããããããšãã¡ã¢ãªå²ãåœãŠãè¡ãããŸãã å€ãã®ããã¯ã¹åæäœãå®è¡ãããšãã¢ããªãžã¡ã¬ãã€ãåäœãŸãã¯ã®ã¬ãã€ãåäœã®ã¡ã¢ãªãå²ãåœãŠãããã¢ããªãããã«å€ãã® GC ã®åå ã«ãªããŸãã .NET Framework ãšèšèªã³ã³ãã€ã©ã§ã¯å¯èœãªéãããã¯ã¹åãåé¿ããŸãããå Žåã«ãã£ãŠã¯ãã»ãšãã©äºæããŠããªãç¶æ³ã§ããã¯ã¹åãè¡ãããããšããããŸãã
PerïœView ã§ããã¯ã¹åã確èªããã«ã¯ããã¬ãŒã¹ãéããã¢ããªã®ããã»ã¹åã®äžã® [GC Heap Alloc Stacks (GC ããŒãå²ãåœãŠã¹ã¿ãã¯)] ãåç §ããŸã (PerfView ã¯ãã¹ãŠã®ããã»ã¹ã«ã€ããŠå ±åããç¹ã«æ³šæããŠãã ãã)ã System.Int32 ã System.Char ã®ãããªåãå²ãåœãŠã®äžã«è¡šç€ºãããå Žåã¯ãå€åãããã¯ã¹åããŠããŸãã ãã®ãããªåã®ãããã 1 ã€ãéžæãããšãåãããã¯ã¹åãããŠããã¹ã¿ãã¯ãšé¢æ°ã衚瀺ãããŸãã
äŸ 1: string ã¡ãœãããšå€ååŒæ°
ãã®ãµã³ãã« ã³ãŒãã¯ãéå°ã§ããäžèŠã§ããå¯èœæ§ã®ããããã¯ã¹åã瀺ããŸãã
public class Logger
{
public static void WriteLine(string s) { /*...*/ }
}
public class BoxingExample
{
public void Log(int id, int size)
{
var s = string.Format("{0}:{1}", id, size);
Logger.WriteLine(s);
}
}
ãã®ã³ãŒãã¯ãã°æ©èœãæäŸããã®ã§ãã¢ããªã¯ Log 颿°ãé »ç¹ã« (æ°çŸäžå) åŒã³åºãããšããããŸãã åé¡ã¯ãstring.Format ã®åŒã³åºãã Format(String, Object, Object) ãªãŒããŒããŒãã«è§£æ±ºãããç¹ã«ãããŸãã
ãã®ãªãŒããŒããŒãã§ã¯ã.NET Framework ã int å€ããªããžã§ã¯ãã«ããã¯ã¹åãããã®ã¡ãœããåŒã³åºãã«æž¡ãå¿
èŠããããŸãã éšåçãªä¿®æ£ãšããŠãid.ToString() ãš size.ToString() ãåŒã³åºãããã¹ãŠã®æåå (ãªããžã§ã¯ã) ã string.Format åŒã³åºãã«æž¡ãæ¹æ³ããããŸãã
ToString() ãåŒã³åºããšæååãå²ãåœãŠãããŸããããã®å²ãåœãŠã¯ string.Format å
éšã§è¡ãããŸãã
ãã®åºæ¬ç㪠string.Format åŒã³åºãã¯åãªãæååã®é£çµã§ãããšèãã代ããã«æ¬¡ã®ãããªã³ãŒããèšè¿°ããããšããããŸãã
var s = id.ToString() + ':' + size.ToString();
ãã ããã®ã³ãŒãè¡ã¯ Concat(Object, Object, Object) ã«ã³ã³ãã€ã«ããããããããã¯ã¹åå²ãåœãŠãè¡ãããŸãã .NET Framework 㯠Concat ãåŒã³åºãããã«æåãªãã©ã«ãããã¯ã¹åããå¿
èŠããããŸãã
äŸ 1 ã®ä¿®æ£
å®å šãªä¿®æ£çã¯åçŽã§ãã æåãªãã©ã«ãæååãªãã©ã«ã«çœ®ãæããã ãã§ãããã®å Žåãæååã¯æ¢ã«ãªããžã§ã¯ãã§ããããããã¯ã¹åã¯çºçããŸããã
var s = id.ToString() + ":" + size.ToString();
äŸ 2: åæåã®ããã¯ã¹å
ãã®äŸã§ã¯ãç¹ã«ãã£ã¯ã·ã§ããªæ€çŽ¢æäœã§åæåãé »ç¹ã«äœ¿çšãããããšãåå ã§ãæ°ãã C# ããã³ Visual Basic ã³ã³ãã€ã©ã§ã¡ã¢ãªã倧éã«å²ãåœãŠãããŸãã
public enum Color
{
Red, Green, Blue
}
public class BoxingExample
{
private string name;
private Color color;
public override int GetHashCode()
{
return name.GetHashCode() ^ color.GetHashCode();
}
}
ããã¯ãéåžžã«åŸ®åŠãªåé¡ã§ãã PerfView ã§ã¯ãã㯠GetHashCode() ã«ããããã¯ã¹åãšããŠå ±åãããŸããããã¯ãå®è£ äžã®çç±ãããã®ã¡ãœãããåæåã®åºã«ãªã衚çŸãããã¯ã¹åããããã§ãã PerfView ã§è©³ãã調ã¹ããšãGetHashCode() ãžã®åŒã³åºãããšã«ãããã¯ã¹åå²ãåœãŠã 2 ã€ããããšãåãããŸãã ã³ã³ãã€ã©ãš .NET Framework ããããã 1 ã€ãã€æ¿å ¥ããŸãã
äŸ 2 ã®ä¿®æ£
äž¡æ¹ã®å²ãåœãŠã容æã«åé¿ã§ããŸãããã®ããã«ã¯ãGetHashCode() ãåŒã³åºãåã«åºãšãªã衚çŸã«ãã£ã¹ãããŸãã
((int)color).GetHashCode()
åæåã«å¯Ÿããããã¯ã¹åã®ãã 1 ã€ã®äžè¬çãªåå ã¯ãEnum.HasFlag(Enum) ã¡ãœããã§ãã HasFlag(Enum) ã«æž¡ãåŒæ°ãããã¯ã¹åããå¿ èŠããããŸãã ã»ãšãã©ã®å ŽåãEnum.HasFlag(Enum) ã®åŒã³åºãããããæŒç®ãã¹ãã«çœ®ãæããæ¹æ³ã®ã»ããç°¡åã§ããããŸãå²ãåœãŠãçºçããŸããã
ããã©ãŒãã³ã¹ã«é¢ãã 1 çªç®ã®äºå® (äžå®å šãªæé©åã¯è¡ããªã) ã«çæãããã®ãããªæ¹æ³ã§ã³ãŒãå šäœãäœæãçŽããªãã§ãã ããã ããã¯ã¹åã®ã³ã¹ãã«æ³šæããŠãã ããããã ããã³ãŒãã倿Žããã®ã¯ãã¢ããªããããã¡ã€ã«ããŠãããã¹ããããæ€åºããåŸã«è¡ãã¹ãã§ãã
æåå
æååæäœã¯ãå²ãåœãŠãçºçããæã倧ããªåå ã® 1 ã€ã§ãããPerfView ã§äžäœ 5 ä»¶ã®å²ãåœãŠã«è¡šç€ºãããããšããããããŸãã ããã°ã©ã ã¯ã·ãªã¢ã«åãJSONãããã³ REST API ã«æååã䜿çšããŸãã åæåã䜿çšã§ããªãå Žåã¯ãã·ã¹ãã ãšã®çžäºéçšã®ããã«ããã°ã©ã 宿°ãšããŠæååã䜿çšã§ããŸãã æååãããã©ãŒãã³ã¹ã«å€§ãã圱é¿ããŠããããšããããã¡ã€ãªã³ã°ã«ãã£ãŠæããã«ãªãå Žåã¯ãString ã¡ãœãã (FormatãConcatãSplitãJoinãSubstring ãªã©) ã®åŒã³åºããæ¢ããŸãã StringBuilder ã䜿çšãããšãè€æ°ã®èŠçŽ ãã 1 ã€ã®æååãäœæããã³ã¹ããåé¿ã§ããŸãããã ã StringBuilder ãªããžã§ã¯ãã®å²ãåœãŠã§ãããã管çããå¿ èŠãããããã«ããã¯ãšãªãããšããããŸãã
äŸ 3: æååæäœ
C# ã³ã³ãã€ã©ã«ã¯ãæžåŒèšå®ããã XML Doc ã³ã¡ã³ãã®ããã¹ããæžãèŸŒãæ¬¡ã®ã³ãŒãããããŸããã
public void WriteFormattedDocComment(string text)
{
string[] lines = text.Split(new[] { "\r\n", "\r", "\n" },
StringSplitOptions.None);
int numLines = lines.Length;
bool skipSpace = true;
if (lines[0].TrimStart().StartsWith("///"))
{
for (int i = 0; i < numLines; i++)
{
string trimmed = lines[i].TrimStart();
if (trimmed.Length < 4 || !char.IsWhiteSpace(trimmed[3]))
{
skipSpace = false;
break;
}
}
int substringStart = skipSpace ? 4 : 3;
for (int i = 0; i < numLines; i++)
WriteLine(lines[i].TrimStart().Substring(substringStart));
}
else { /* ... */ }
ãã®ã³ãŒãã«ãã£ãŠå€§éã®æååæäœãå®è¡ãããŠããããšãããããŸãã ãã®ã³ãŒãã¯ã©ã€ãã©ãª ã¡ãœããã䜿çšããŠãè¡ãåã
ã®æååã«åå²ãã空çœãããªãã³ã°ããåŒæ° text ã XML ããã¥ã¡ã³ã ã³ã¡ã³ãã§ãããã©ããã確èªããè¡ããéšåæååãæœåºããŸãã
WriteFormattedDocComment å
éšã®æåã®è¡ã§ã¯ãtext.Split ãåŒã³åºããããã³ã«ã3 ã€ã®èŠçŽ ãããªãæ°ããé
åãåŒæ°ãšããŠå²ãåœãŠãããŸãã ã³ã³ãã€ã©ã¯ããã®é
åãå²ãåœãŠãã³ãŒããæ¯ååºåããå¿
èŠããããŸãã ããã¯ãSplit ã«ããé
åã®æ ŒçŽå
ã§ããã®é
åãä»ã®ã³ãŒãã«ãã£ãŠå€æŽãããå¯èœæ§ããããã©ãããã³ã³ãã€ã©ãèªèã§ããªãããã§ãã倿Žãããå Žåã¯ãåŸã® WriteFormattedDocComment åŒã³åºãã«åœ±é¿ããããŸãã
Split ã®åŒã³åºãã§ã¯ãtext ã®ãã¹ãŠã®è¡ã«æååãå²ãåœãŠãããæäœãå®è¡ããããã«ä»ã®ã¡ã¢ãªãå²ãåœãŠãããŸãã
WriteFormattedDocComment ã«ã¯ TrimStart ã¡ãœããåŒã³åºãã 3 ã€ãããŸãã ãã®ãã¡ã® 2 ã€ã¯ãåŠçãšå²ãåœãŠãéè€ããå
åŽã®ã«ãŒãå
ã«ãããŸãã ããã«æªãããšã«ãåŒæ°ãªãã§ TrimStart ã¡ãœãããåŒã³åºããšãæååçµæã®ä»ã«ç©ºã®é
å (params ãã©ã¡ãŒã¿ãŒ) ãå²ãåœãŠãããŸãã
æåŸã«ãSubstring ã¡ãœãããåŒã³åºãããŸãããã®ã¡ãœããã¯éåžžãæ°ããæååãå²ãåœãŠãŸãã
äŸ 3 ã®ä¿®æ£
åè¿°ã®äŸãšç°ãªããå°èŠæš¡ãªç·šéã§ã¯ãããã®å²ãåœãŠãä¿®æ£ã§ããŸããã ããã®ãŒã£ãŠåé¡ã調ã¹ãç°ãªãæ¹æ³ã§å¯ŸåŠããå¿
èŠããããŸãã ããšãã°ãWriteFormattedDocComment() ã®åŒæ°ãããã®ã¡ãœããã«å¿
èŠãªæ
å ±ããã¹ãŠå«ãŸããŠããæååã®å Žåãã³ãŒãã§ã¯è€æ°ã®éšåæååãå²ãåœãŠã代ããã«ããã®åå€ãã®ã€ã³ããã¯ã¹äœæåŠçãå®è¡ã§ããŸãã
ã³ã³ãã€ã©ã®ããã©ãŒãã³ã¹ ããŒã ã¯ããã®ãããªå²ãåœãŠã«å¯ŸåŠããããæ¬¡ã®ãããªã³ãŒãã䜿çšããŸããã
private int IndexOfFirstNonWhiteSpaceChar(string text, int start) {
while (start < text.Length && char.IsWhiteSpace(text[start])) start++;
return start;
}
private bool TrimmedStringStartsWith(string text, int start, string prefix) {
start = IndexOfFirstNonWhiteSpaceChar(text, start);
int len = text.Length - start;
if (len < prefix.Length) return false;
for (int i = 0; i < len; i++)
{
if (prefix[i] != text[start + i]) return false;
}
return true;
}
// etc...
WriteFormattedDocComment() ã®æåã®ããŒãžã§ã³ã§ã¯ãé
åãè€æ°ã®éšåæååãããªãã³ã°ãããéšåæååãšç©ºã® params é
åãå²ãåœãŠãããŸããã ãŸãã"///" ã®æç¡ã確èªãããŸããã ä¿®æ£åŸã®ã³ãŒãã¯ãã€ã³ããã¯ã¹äœæã®ã¿ã䜿çšããå²ãåœãŠãè¡ããŸããã 空çœä»¥å€ã®æåã®æåãæ€åºããæåã 1 ã€ãã€èª¿ã¹ãŠæååã "///" ã§å§ãŸã£ãŠãããã©ããã確èªããŸãã ãã®æ°ããã³ãŒãã§ã¯ IndexOfFirstNonWhiteSpaceChar ã®ä»£ããã« TrimStart ã䜿çšããã(æå®ãããéå§ã€ã³ããã¯ã¹ããåŸã§) 空çœä»¥å€ã®æåãå«ãŸããæåã®ã€ã³ããã¯ã¹ãè¿ãããŸãã ãã®ä¿®æ£ã¯å®å
šã§ã¯ãããŸããããå®å
šãªè§£æ±ºçãšããŠé¡äŒŒã®ä¿®æ£ãé©çšããæ¹æ³ãããããŸãã ã³ãŒãå
šäœã§ãã®æ¹æ³ãé©çšããããšã§ãWriteFormattedDocComment() å
ã®ãã¹ãŠã®å²ãåœãŠãåé€ã§ããŸãã
äŸ 4: StringBuilder
ãã®äŸã¯ StringBuilder ãªããžã§ã¯ãã䜿çšããŸãã æ¬¡ã®é¢æ°ã¯ããžã§ããªãã¯åã®å®å šãªååãçæããŸãã
public class Example
{
// Constructs a name like "SomeType<T1, T2, T3>"
public string GenerateFullTypeName(string name, int arity)
{
StringBuilder sb = new StringBuilder();
sb.Append(name);
if (arity != 0)
{
sb.Append("<");
for (int i = 1; i < arity; i++)
{
sb.Append("T"); sb.Append(i.ToString()); sb.Append(", ");
}
sb.Append("T"); sb.Append(i.ToString()); sb.Append(">");
}
return sb.ToString();
}
}
æ°ãã StringBuilder ã€ã³ã¹ã¿ã³ã¹ãäœæããè¡ã«æ³šç®ããŸãã ãã®ã³ãŒããåå ã§ãsb.ToString() ã®å²ãåœãŠãš StringBuilder å®è£
å
ã§ã®å
éšå²ãåœãŠãçºçããŸãããæååã®çµæãå¿
èŠãªå Žåã¯ãããã®å²ãåœãŠãå¶åŸ¡ã§ããŸããã
äŸ 4 ã®ä¿®æ£
StringBuilder ãªããžã§ã¯ãã®å²ãåœãŠãä¿®æ£ããã«ã¯ããã®ãªããžã§ã¯ãããã£ãã·ã¥ããŸãã ç Žæ£ãããå¯èœæ§ããã 1 ã€ã®ã€ã³ã¹ã¿ã³ã¹ããã£ãã·ã¥ããã ãã§ããããã©ãŒãã³ã¹ã倧å¹
ã«æ¹åãããããšããããŸãã ããã¯é¢æ°ã®æ°ããå®è£
ã§ãããæ°ããæåã®è¡ãšæåŸã®è¡ãé€ããã¹ãŠã®ã³ãŒããçç¥ããŠããŸãã
// Constructs a name like "MyType<T1, T2, T3>"
public string GenerateFullTypeName(string name, int arity)
{
StringBuilder sb = AcquireBuilder();
/* Use sb as before */
return GetStringAndReleaseBuilder(sb);
}
éèŠãªã®ã¯ãæ°ãã AcquireBuilder() ããã³ GetStringAndReleaseBuilder() 颿°ã§ãã
[ThreadStatic]
private static StringBuilder cachedStringBuilder;
private static StringBuilder AcquireBuilder()
{
StringBuilder result = cachedStringBuilder;
if (result == null)
{
return new StringBuilder();
}
result.Clear();
cachedStringBuilder = null;
return result;
}
private static string GetStringAndReleaseBuilder(StringBuilder sb)
{
string result = sb.ToString();
cachedStringBuilder = sb;
return result;
}
æ°ããã³ã³ãã€ã©ã¯ã¹ã¬ããåŠçã䜿çšããããããã®ãããªå®è£
㯠thread-static ãã£ãŒã«ã (ThreadStaticAttribute 屿§) ã䜿çšã㊠StringBuilder ããã£ãã·ã¥ããŸãããã®ãã ThreadStatic 宣èšã䜿çšããã«æžãŸããããšãã§ããŸãã thread-static ãã£ãŒã«ãã«ã¯ããã®ã³ãŒããå®è¡ããåã¹ã¬ããã®äžæã®å€ãæ ŒçŽãããŸãã
AcquireBuilder() ã¯ããã£ãã·ã¥ããã StringBuilder ã€ã³ã¹ã¿ã³ã¹ãããå Žåã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãè¿ããŸãããã®åŸããã®ã€ã³ã¹ã¿ã³ã¹ãã¯ãªã¢ããŠãã£ãŒã«ããŸãã¯ãã£ãã·ã¥ã Null ã«èšå®ããŸãã ãã以å€ã®å Žåã¯ãAcquireBuilder() ã¯æ°èŠã€ã³ã¹ã¿ã³ã¹ãäœæããŠè¿ãããã£ãŒã«ããŸãã¯ãã£ãã·ã¥ã¯ Null ã«èšå®ãããŸãŸã«ããŸãã
StringBuilder ã®åŠçãå®äºããããGetStringAndReleaseBuilder() ãåŒã³åºããŠæååçµæãååŸãããã£ãŒã«ããŸãã¯ãã£ãã·ã¥ã« StringBuilder ã€ã³ã¹ã¿ã³ã¹ãä¿åããçµæãè¿ããŸãã å®è¡æã«ãã®ã³ãŒãã«åã³å
¥ããè€æ°ã® StringBuilder ãªããžã§ã¯ããäœæãããå¯èœæ§ããããŸã (ãã ãè€æ°ãªããžã§ã¯ããäœæãããããšã¯ã»ãšãã©ãããŸãã)ã ãã®ã³ãŒãã¯æåŸã«è§£æŸããã StringBuilder ã€ã³ã¹ã¿ã³ã¹ã ãããåŸã§äœ¿çšã§ããããã«ä¿åããŸãã ãã®åçŽãªãã£ãã·ã¥å¯Ÿçã«ãã£ãŠãæ°ããã³ã³ãã€ã©ã§ã®å²ãåœãŠã倧å¹
ã«æžå°ããŸããã .NET Framework ãš MSBuild ("MSBuild") ã®äžéšã§ã¯ãããã©ãŒãã³ã¹æ¹åã®ããã«é¡äŒŒã®ææ³ã䜿çšãããŠããŸãã
ãµã€ãºå¶éãããããããã®åçŽãªãã£ãã·ã¥å¯Ÿçã¯é©åãªãã£ãã·ã¥èšèšã«æºæ ããŠããŸãã ãã ããå ã®ããŒãžã§ã³ãããã³ãŒããå¢ãããããä¿å®ã³ã¹ããå¢å ããŸãã ãã®ãã£ãã·ã¥å¯Ÿçãåãå ¥ããã®ã¯ãããã©ãŒãã³ã¹ã®åé¡ãæ€åºããPerfView ã§ StringBuilder å²ãåœãŠããã®åé¡ã®å€§ããªåå ã§ããããšã瀺ãããŠããå Žåã ãã«ããŠãã ããã
LINQ ãšã©ã ã
ã©ã ãåŒãšçµã¿åãããçµ±åèšèªã¯ãšãª (LINQ) ã¯ãçç£æ§åäžæ©èœã®äžäŸã§ãã ãã ãããã®äœ¿çšã¯ãæéã®çµéãšå ±ã«ããã©ãŒãã³ã¹ã«å€§ããªåœ±é¿ãäžãããããããããã³ãŒãã®åäœæãå¿ èŠã«ãªãå ŽåããããŸãã
äŸ 5: ã©ã ããList<T>ãããã³ IEnumerable<T>
ãã®äŸã§ã¯ãLINQ ãšé¢æ°ã¹ã¿ã€ã«ã®ã³ãŒããå©çšããäžããããååæååã§ãã³ã³ãã€ã©ã®ã¢ãã«ã§èšå·ãæ¢ããŸãã
class Symbol {
public string Name { get; private set; }
/*...*/
}
class Compiler {
private List<Symbol> symbols;
public Symbol FindMatchingSymbol(string name)
{
return symbols.FirstOrDefault(s => s.Name == name);
}
}
æ°ããã³ã³ãã€ã©ãšããã®ã³ã³ãã€ã©äžã«æ§ç¯ããã IDE æ©èœã¯ FindMatchingSymbol() ãããªãé »ç¹ã«åŒã³åºããŸãããã®é¢æ°ãèšè¿°ãã 1 è¡ã®ã³ãŒãã«ã¯ãå²ãåœãŠãããã€ãé ãããŠããŸãã ãã®ãããªå²ãåœãŠã調ã¹ãã«ã¯ããŸã颿°ãèšè¿°ãã 1 è¡ã®ã³ãŒãã 2 è¡ã«åå²ããŸãã
Func<Symbol, bool> predicate = s => s.Name == name;
return symbols.FirstOrDefault(predicate);
æåã®è¡ã§ãã©ã ãåŒs => s.Name == nameãããŒã«ã«å€æ°ãnameãã£ããã£ããŸãã ã€ãŸãããã®ã³ãŒã㯠ãä¿æããŠããpredicateã«ãªããžã§ã¯ããå²ãåœãŠã以å€ã«ãname ã®å€ããã£ããã£ããç°å¢ãä¿æããéçã¯ã©ã¹ãå²ãåœãŠãŸãã ã³ã³ãã€ã©ã¯æ¬¡ã®ãããªã³ãŒããçæããŸãã
// Compiler-generated class to hold environment state for lambda
private class Lambda1Environment
{
public string capturedName;
public bool Evaluate(Symbol s)
{
return s.Name == this.capturedName;
}
}
// Expanded Func<Symbol, bool> predicate = s => s.Name == name;
Lambda1Environment l = new Lambda1Environment() { capturedName = name };
var predicate = new Func<Symbol, bool>(l.Evaluate);
ããã§ã¯ 2 ã€ã® new å²ãåœãŠ (ç°å¢ã¯ã©ã¹ã«å¯Ÿããå²ãåœãŠãšããªã²ãŒãã«å¯Ÿããå²ãåœãŠ) ãæç€ºçã«è¡ãããŸãã
次ã«FirstOrDefaultã®åŒã³åºãã調ã¹ãŸãã
System.Collections.Generic.IEnumerable<T> åã«å¯Ÿãããã®æ¡åŒµã¡ãœããã§ãå²ãåœãŠãçºçããŸãã
FirstOrDefault ã IEnumerable<T> ãªããžã§ã¯ããæåã®åŒæ°ãšããŠåãåãããããã®åŒã³åºããæ¡åŒµããŠæ¬¡ã®ã³ãŒãã®ããã«ã§ããŸã (ãã®ã³ãŒãã¯èª¬æã®ããåçŽåãããŠããŸã)ã
// Expanded return symbols.FirstOrDefault(predicate) ...
IEnumerable<Symbol> enumerable = symbols;
IEnumerator<Symbol> enumerator = enumerable.GetEnumerator();
while(enumerator.MoveNext())
{
if (predicate(enumerator.Current))
return enumerator.Current;
}
return default(Symbol);
symbols 倿°ã®å㯠List<T> ã§ãã
List<T> ã³ã¬ã¯ã·ã§ã³å㯠IEnumerable<T> ãå®è£
ããIEnumerator<T> ã List<T>ã䜿çšããŠå®è£
ããåæå (struct ã€ã³ã¿ãŒãã§ã€ã¹) ãé©åã«å®çŸ©ããŸãã ã¯ã©ã¹ã®ä»£ããã«æ§é äœã䜿çšãããšãéåžžããŒãå²ãåœãŠãåé¿ã§ãããããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã®ããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ããããŸãã éåžžãåæåã¯èšèªã® foreach ã«ãŒãã§äœ¿çšãããŸãããã®ã«ãŒãã¯ãã³ãŒã« ã¹ã¿ãã¯ã§è¿ãããåæåæ§é ã䜿çšããŸãã ãªããžã§ã¯ãã®ã¹ããŒã¹ã確ä¿ããããã«ã³ãŒã« ã¹ã¿ã㯠ãã€ã³ã¿ãŒãã€ã³ã¯ãªã¡ã³ãããŠããGC ã¯ããŒãå²ãåœãŠã®ãããªåœ±é¿ãåããŸããã
æ¡åŒµ FirstOrDefault åŒã³åºãã®å Žåããã®ã³ãŒãã¯GetEnumerator() ã«å¯Ÿã㊠IEnumerable<T> ãåŒã³åºãå¿
èŠããããŸãã
symbols ã enumerable åã® IEnumerable<Symbol> 倿°ã«å²ãåœãŠããšãå®éã®ãªããžã§ã¯ãã List<T> ã§ãããšããæ
å ±ã倱ãããŸãã. ã€ãŸããã³ãŒãã enumerable.GetEnumerator() ã§åæåããã§ãããããšãã«ã¯ã.NET Framework ã¯è¿ãããæ§é äœãããã¯ã¹åããenumerator 倿°ã«å²ãåœãŠãå¿
èŠããããŸãã
äŸ 5 ã®ä¿®æ£
ãã®ä¿®æ£ã§ã¯ãFindMatchingSymbol ãæ¬¡ã®ããã«æžãçŽãã1 ã€ã®ã³ãŒãè¡ã 6 è¡ã®ã³ãŒãè¡ã«çœ®ãæããŸãããã® 6 è¡ã®ã³ãŒãã¯ç°¡æœã§ãããèªãã§çè§£ããããããŸãä¿å®ã容æã§ãã
public Symbol FindMatchingSymbol(string name)
{
foreach (Symbol s in symbols)
{
if (s.Name == name)
return s;
}
return null;
}
ãã®ã³ãŒã㯠LINQ æ¡åŒµã¡ãœãããã©ã ããåæåã䜿çšããªããããå²ãåœãŠã®åé¡ã¯çºçããŸããã
symbols ã³ã¬ã¯ã·ã§ã³ã List<T> ã§ããããšãã³ã³ãã€ã©ãèªèã§ããçµæåæå (æ§é äœ) ãé©åãªåã®ããŒã«ã«å€æ°ã«ãã€ã³ãããŠããã¯ã¹åãåé¿ã§ãããããå²ãåœãŠãçºçããŸããã ãã®é¢æ°ã®å
ã®ããŒãžã§ã³ã¯ãC# ã®é«ãæ§èœãš .NET Framework ã®çç£æ§ã瀺ãæé©ãªäŸã§ããã ãã®æ°ããå¹çæ§ãé«ãããŒãžã§ã³ã¯ãä¿å®ã®ããã«è€éãªã³ãŒãã远å ããããšãªãããã®ãããªå質ãä¿æããŸãã
éåæã¡ãœãããã£ãã·ã¥
次ã®äŸã¯ããã£ãã·ã¥ãããçµæãéåæã¡ãœããã§äœ¿çšããããšãããšçºçããäžè¬çãªåé¡ã瀺ããŸãã
äŸ 6: éåæã¡ãœããã§ã®ãã£ãã·ã¥
æ°ãã C# ããã³ Visual Basic ã³ã³ãã€ã©äžã«æ§ç¯ããã Visual Studio IDE æ©èœã¯ãæ§æããªãŒãé »ç¹ã«ãã§ããããŸããã³ã³ãã€ã©ã¯ãVisual Studio ã®å¿çæ§ãç¶æããããã«éåæã䜿çšããŸãã æ§æããªãŒãååŸããç®çã§äœæããã³ãŒãã®æåã®ããŒãžã§ã³ã次ã«ç€ºããŸãã
class SyntaxTree { /*...*/ }
class Parser { /*...*/
public SyntaxTree Syntax { get; }
public Task ParseSourceCode() { /*...*/ }
}
class Compilation { /*...*/
public async Task<SyntaxTree> GetSyntaxTreeAsync()
{
var parser = new Parser(); // allocation
await parser.ParseSourceCode(); // expensive
return parser.Syntax;
}
}
GetSyntaxTreeAsync() ãåŒã³åºããš Parser ãã€ã³ã¹ã¿ã³ã¹åãããã³ãŒããè§£æãããTask ãªããžã§ã¯ããè¿ãããããšãããããŸããTask<SyntaxTree>. ã³ã¹ãããããéšåã¯ãParser ã€ã³ã¹ã¿ã³ã¹ã®å²ãåœãŠãšã³ãŒãã®è§£æã§ãã ãã®é¢æ°ã¯ Task ãè¿ãã®ã§ãåŒã³åºãå
ã¯ãŠãŒã¶ãŒå
¥åã«å¿çããããã«è§£æäœæ¥ãåŸ
ã¡ãUI ã¹ã¬ãããè§£æŸã§ããŸãã
Visual Studio ã®è€æ°ã®æ©èœãåãæ§æããªãŒãååŸããããšããããšããããããè§£æçµæããã£ãã·ã¥ããæ¬¡ã®ã³ãŒããèšè¿°ãããšãæéãšå²ãåœãŠãç¯çŽã§ããŸãã ãã ããã®ã³ãŒãã§ã¯å²ãåœãŠãçºçããŸãã
class Compilation { /*...*/
private SyntaxTree cachedResult;
public async Task<SyntaxTree> GetSyntaxTreeAsync()
{
if (this.cachedResult == null)
{
var parser = new Parser(); // allocation
await parser.ParseSourceCode(); // expensive
this.cachedResult = parser.Syntax;
}
return this.cachedResult;
}
}
ãã£ãã·ã¥ã«é¢ããæ°ããã³ãŒãã«ã¯ SyntaxTree ãšããååã® cachedResult ãã£ãŒã«ãããããŸãã ãã®ãã£ãŒã«ãã Null ã®å ŽåãGetSyntaxTreeAsync() ãåŠçãè¡ãããã£ãã·ã¥ã«çµæãä¿åãããŸãã
GetSyntaxTreeAsync() 㯠SyntaxTree ãªããžã§ã¯ããè¿ããŸãã ããã§åé¡ãšãªãã®ã¯ãasync åã® Task<SyntaxTree> 颿°ããããSyntaxTree åã®å€ãè¿ãå Žåãã³ã³ãã€ã©ãã(Task<SyntaxTree>.FromResult() ã䜿çšããŠ) çµæãä¿æããããã« Task ãå²ãåœãŠãã³ãŒããåºåããããšã§ãã Task ã¯å®äºæžã¿ãšããŠããŒã¯ãããçµæã峿ã«å©çšå¯èœã«ãªããŸãã æ°ããã³ã³ãã€ã©ã®ã³ãŒãã§ã¯ãæ¢ã«å®äºããŠãã Task ãªããžã§ã¯ããé »ç¹ã«çºçããããããã®ãããªå²ãåœãŠãä¿®æ£ãããšå¿çæ§ãèããåäžããããšããããããŸããã
äŸ 6 ã®ä¿®æ£
å®äºãã Task å²ãåœãŠãåé€ããã«ã¯ãå®äºããçµæãšå ±ã« Task ãªããžã§ã¯ãããã£ãã·ã¥ã§ããŸãã
class Compilation { /*...*/
private Task<SyntaxTree> cachedResult;
public Task<SyntaxTree> GetSyntaxTreeAsync()
{
return this.cachedResult ??
(this.cachedResult = GetSyntaxTreeUncachedAsync());
}
private async Task<SyntaxTree> GetSyntaxTreeUncachedAsync()
{
var parser = new Parser(); // allocation
await parser.ParseSourceCode(); // expensive
return parser.Syntax;
}
}
ãã®ã³ãŒã㯠cachedResult ã®åã Task<SyntaxTree> ã«å€æŽããasync ããã®å
ã®ã³ãŒããä¿æãã GetSyntaxTreeAsync() ãã«ããŒé¢æ°ãæ¡çšããŠããŸãã
GetSyntaxTreeAsync() 㯠null åäœæŒç®åã䜿çšããŠãcachedResult ã null ã§ãªãå Žåã«ãããè¿ããŸãã
cachedResult ã null ã®å ŽåãGetSyntaxTreeAsync() 㯠GetSyntaxTreeUncachedAsync() ãåŒã³åºããçµæããã£ãã·ã¥ããŸãã
GetSyntaxTreeAsync() ã¯ãéåžžã®ã³ãŒãã®ããã«ã¯ãGetSyntaxTreeUncachedAsync() åŒã³åºããåŸ
ããªãããšã«æ³šæããŠãã ããã åŸ
æ©ããªããšããããšã¯ãGetSyntaxTreeUncachedAsync() ããã® Task ãªããžã§ã¯ããè¿ãå ŽåãGetSyntaxTreeAsync() ã峿ã«Task ãè¿ãããšã«ãªããŸãã ãã®æç¹ã§ããã£ãã·ã¥ãããçµæã¯ Task ã§ããããããã£ã·ã¥ãããçµæãè¿ãããã®å²ãåœãŠã¯è¡ãããŸããã
ãã®ä»ã®æ³šæç¹
倧ããªã¢ããªãŸãã¯å€§éããŒã¿ãåŠçããã¢ããªã§çºçããå¯èœæ§ãããåé¡ã«é¢ãããã®ä»ã®ç¹ã次ã«èª¬æããŸãã
èŸæž
ãã£ã¯ã·ã§ããªã¯å€ãã®ããã°ã©ã ã§éæã«äœ¿çšãããŠãããéåžžã«äŸ¿å©ã§æ¬è³ªçã«å¹ççã§ãã ãã ããäœ¿ãæ¹ãäžé©åãªããšããããããŸãã Visual Studio ãšæ°ããã³ã³ãã€ã©ã§ã¯ãåæãããå€ãã®ãã£ã¯ã·ã§ããªã§ã¯å«ãŸããŠããèŠçŽ ã 1ã€ã ãã§ããããäœãå«ãŸããŠããªãããšã倿ããŸããã x86 ãã·ã³ã§ã¯ã空㮠Dictionary<TKey,TValue> ã«ã¯ 10 åã®ãã£ãŒã«ãããããããŒãã§ 48 ãã€ããå æããŠããŸãã ãã£ã¯ã·ã§ããªã圹ç«ã€ã®ã¯ãäžå®æéå
ã®æ€çŽ¢ã®ãããã³ã°ãŸãã¯é¢é£ããŒã¿æ§é äœãå¿
èŠãªå Žåã§ãã ãã ãèŠçŽ ã®æ°ãå°ãªãå Žåã¯ããã£ã¯ã·ã§ããªã䜿çšãããšã¹ããŒã¹ãç¡é§ã«äœ¿çšããããšã«ãªããŸãã 代ããã«ãããšãã° List<KeyValuePair\<K,V>> ã®ç¹°ãè¿ãæ€çŽ¢ããåãé床ã§è¡ããŸãã ãã£ã¯ã·ã§ããªãããŒã¿ã®èªã¿æžãã ãã«äœ¿çšããå ŽåïŒéåžžã«ãããããã¿ãŒã³ïŒãN(log(N)) ã®æ¢çŽ¢ãè¡ããœãŒãæžã¿é
åã䜿ãããšã§ã䜿çšããèŠçŽ æ°ã«å¿ããŠãã»ãŒåãé床ãåŸãããããšããããŸãã
ã¯ã©ã¹ãšæ§é äœ
ã¯ã©ã¹ãšæ§é äœã¯ãã¢ããªã調æŽããäžã§åŸæ¥åã®ã¹ããŒã¹/æéã®ãã¬ãŒããªããçããããŸãã ãã£ãŒã«ããå«ãŸããŠããªãã¯ã©ã¹ã§ã¯ãx86 ãã·ã³ã§ 12 ãã€ãã®ãªãŒããŒããããçããŸãããã¯ã©ã¹ ã€ã³ã¹ã¿ã³ã¹ãæããã€ã³ã¿ãã ããåãåãã®ã§ãã¯ã©ã¹ã®åãæž¡ãã«ãããã³ã¹ãã¯äœããªããŸãã ããã¯ã¹åãããŠããªãæ§é äœã®å ŽåãããŒãå²ãåœãŠã¯è¡ãããŸãããã倧ããªæ§é äœã颿°ã®åŒæ°ãŸãã¯æ»ãå€ãšããŠæž¡ããšãæ§é äœã®ãã¹ãŠã®ããŒã¿ ã¡ã³ããŒãã¢ãããã¯ã«ã³ããŒããããã«ãCPU æéãããããŸãã æ§é äœãè¿ãããããã£åŒã³åºãã®ç¹°ãè¿ãã«æ³šæããéå°ãªããŒã¿ ã³ããŒãè¡ããªãããã«ãããããããããã£ã®å€ãããŒã«ã«å€æ°ã«ãã£ãã·ã¥ããŸãã
ãã£ãã·ã¥
äžè¬çãªããã©ãŒãã³ã¹åäžã®ããã®ãã¯ããã¯ã¯ãçµæããã£ãã·ã¥ããããšã§ãã ãã ãããµã€ãºå¶éãç Žæ£ããªã·ãŒãèšå®ãããŠããªããã£ãã·ã¥ã¯ã¡ã¢ãª ãªãŒã¯ãšãªãå¯èœæ§ããããŸãã 倧éã®ããŒã¿ãåŠçããéã«ããã£ãã·ã¥ã«å€§éã®ã¡ã¢ãªãä¿æããŠãããšãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã«ãã£ãŠãã£ãã·ã¥ããæ€çŽ¢æ©èœã®ã¡ãªãããæã¡æ¶ãããå¯èœæ§ããããŸãã
ãã®èšäºã§ã¯ãç¹ã«å€§èŠæš¡ã·ã¹ãã ã倧éã®ããŒã¿ãåŠçããã·ã¹ãã ã«ãããŠãã¢ããªã®å¿çæ§ã«åœ±é¿ããå¯èœæ§ãããããã©ãŒãã³ã¹ã®ããã«ããã¯ã®çç¶ã«ã©ã®ããã«æ³šæããããããã説æããŸããã äžè¬çãªåé¡ã«ã¯ãããã¯ã¹åãæååæäœãLINQ ããã³ã©ã ããéåææ¹åŒã§ã®ãã£ãã·ã¥ããµã€ãºå¶éãŸãã¯ç Žæ£ããªã·ãŒã®ãªããã£ãã·ã¥ãäžé©åãªãã£ã¯ã·ã§ããªã®äœ¿çšãæ§é äœã®åãæž¡ããªã©ããããŸãã ã¢ããªã®èª¿æŽã«é¢ãã 4 ã€ã®äºå®ã«æ³šæããŠãã ããã
äžå®å šãªæé©åã¯è¡ããªã - çç£çã«äœæ¥ããåé¡ãèŠã€ãããã¢ããªã調æŽããŸãã
ãããã¡ã€ã«ã¯åãã€ããªã - 枬å®ããŠããªãã®ã§ããã°ãæšæž¬ã«ãããŸããã
åªããããŒã«ã«ã¯å€§ããªå¹æããã - PerfView ãããŠã³ããŒãããŠè©ŠããŠã¿ãŠãã ããã
ãã¹ãŠã¯å²ãåœãŠã§æ±ºãŸã - ã³ã³ãã€ã© ãã©ãããã©ãŒã ããŒã ã¯ãæ°ããã³ã³ãã€ã©ã®ããã©ãŒãã³ã¹ã®åäžã®ããããã®åéã«æãå€ãã®æéããããŸããã