ãšã³ããªãŒ
ç§ã®æåŸã®èšäºã¯ã.NETã®StringããŒã¿åStringã®æ©èœã«ã€ããŠã§ããã ãã®èšäºã§ã¯äŒçµ±ãç¶ããŠããŸãããä»åã¯StringBuilderã¯ã©ã¹ãåãäžããŸãã
ãåç¥ã®ããã«ã.NETã®æååã¯ïŒå®å šã§ã¯ãªãïŒäžå€ã§ããããããããã«å¯ŸããŠå€§èŠæš¡ãªé£çµæäœãå®è¡ããããšã¯ãå§ãã§ããŸããã ããã¯ã次ã®ã³ãŒãã«éåžžã«æ·±å»ãªã¡ã¢ãªè² è·ã®åé¡ãããããšãæå³ããŸãã
string s = string.Empty; for (int i = 0; i < 100; i++) { s += "T"; }
ãã®ã³ãŒãã®äœããããªã«æªãã®ã§ããïŒ ãããŠãåå埩ã§ãåã®ã¹ãããããã1åäœé·ãè¡ãäœæããããã®åŸã«å€ãè¡ããæåãã³ããŒããããšããäºå®ã ãããã£ãŠãé¢ä¿ããæåã®ç·æ°ã¯æ¬¡ãšçãããªããŸãã
ãã®åŒã¯ãç®è¡æ°åã®åèšã«éããŸããïŒ
ã€ãŸãããã®ãããªé£çµã·ããªãªã§ã¯ãOïŒn 2 ïŒã«æ¯äŸããã¡ã¢ãªãå¿ èŠã§ããnã¯æååã®é·ãã§ãã
ãã®ãããªã³ãŒãã®åé¡ãä¿®æ£ããã«ã¯ãStringBuilderã¯ã©ã¹ã䜿çšããŸãããã®ã¯ã©ã¹ã䜿çšããæäœã¯ãStringã®ãããªã¡ã¢ãªã®æµªè²»ã«ã€ãªãããªãããšãèªèããŠããŸãã å®éãStringBuilderã¯å€æŽå¯èœãªæååã§ãã
var strB = new StringBuilder(); for (int i = 0; i < 100; i++) { strB.Append("T"); } string str = strB.ToString();
ãã®ãããªã³ãŒãã¯ããã¹ãŠã®æ¬ é¥ããªãããã§ã¯ãããŸãããã颚ã®äžã§ããããã®ã¡ã¢ãªã浪費ããŸããã以åã®ã³ãŒãã«æ¯ã¹ãŠããæå¶ãããŠããŸãã
StringBuilderã¯ã©ã¹ã®å®è£ ã¯ã以åã®ããŒãžã§ã³ãšæ¯èŒããŠ.NET 4.0ã§åçã«å€æŽããããããäœãèµ·ãã£ãã®ããæžãããšã¯èå³æ·±ããšæããŸãã
.NET 2.0ã®StringBuilder
.NET 2.0ã®StringBuilderã¯ã©ã¹ã«ã¯ã次ã®ãã£ãŒã«ãããããŸãã
public sealed class StringBuilder : ISerializable { internal const int DefaultCapacity = 16; private const string CapacityField = "Capacity"; private const string MaxCapacityField = "m_MaxCapacity"; private const string StringValueField = "m_StringValue"; private const string ThreadIDField = "m_currentThread"; internal IntPtr m_currentThread; internal int m_MaxCapacity; internal volatile string m_StringValue; <------------------------------------- }
m_currentThread-ãªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãäœæãããã¹ã¬ããã®èå¥åã
m_MaxCapacity-ãã®ã€ã³ã¹ã¿ã³ã¹ã®æ倧容éã
m_StringValueã¯ãæåãå«ãæååã§ãã
å®éãStringBuilderã¯ã©ã¹ã¯å éšçã«StringããŒã¿åStringã§åäœããŸãã mscorlib.dllåŽã®æååã¯å¯å€ã§ãããããStringBuilderã¯m_StringValueã«ããæååãå€æŽããããã®è²»çšã¯ããããŸããã
åæã®é·ãã¯16æåã§ããæ°ããæåãè¿œå ããã®ã«ååãªã¹ããŒã¹ããªãå ŽåãStringBuilderã¯å éšã®æååã2åã®é·ãã®æååã«çœ®ãæããåã®+æ°ããæååããæ°ããäœæããããã¹ãŠã®æåã«ã³ããŒããŸãã æååã®é·ãã2åã«ãããšãéåžžã®æååã«åºæã®2次ãšã¯ç°ãªããã¡ã¢ãªå ã§ç·åœ¢ã®è€éãïŒOïŒnïŒïŒãçããŸãã
ããã©ãŒãã³ã¹ãåäžãããããã®éèŠãªè¿œå ã¯ãStringBuilderã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãäœæãããšãã«å¿ èŠãªå®¹éãèšå®ããããšã§ãã ãããã£ãŠããµã€ãºãããã«2åã«ããã¡ã¢ãªäžè¶³ã§ããŒã¿ãã³ããŒããå¿ èŠã¯ãããŸããã ãã ããããã¯ãçµæã®æååã®ãµã€ãºãäºåã«ããã£ãŠããå Žåã«ã®ã¿å¯èœã§ãã
æãäžè¬çã«äœ¿çšãããæ¹æ³ã®å®è£ ãæ€èšããŠãã ããã ã³ãŒããèªã¿ãããããããã«ãå ¥åãã©ã¡ãŒã¿ãŒããã§ãã¯ããããã®æ¡ä»¶ãåé€ããŸããã
AppendïŒïŒã¡ãœãã
ãœãŒã¹ã³ãŒã
public StringBuilder Append(string value) { if (value == null) return this; string currentString = this.m_StringValue; IntPtr currentThread = Thread.InternalGetCurrentThread(); if (this.m_currentThread != currentThread) currentString = string.GetStringForStringBuilder(currentString, currentString.Capacity); int length = currentString.Length; int requiredLength = length + value.Length; if (this.NeedsAllocation(currentString, requiredLength)) // { // 2 string newString = this.GetNewString(currentString, requiredLength); newString.AppendInPlace(value, length); this.ReplaceString(currentThread, newString); // } else { currentString.AppendInPlace(value, length); this.ReplaceString(currentThread, currentString); } return this; }
ãã®ã¡ãœããã¯ãçŸåšã®ã€ã³ã¹ã¿ã³ã¹ã«æ°ããè¡ãè¿œå ããã®ã«ååãªã¹ããŒã¹ããããã©ããã確èªããŸããã¹ããŒã¹ãããå Žåã¯ãåã«è¡ã®ç©ºããŠããéšåã«ã³ããŒããŸããããã§ãªãå Žåã¯ããµã€ãºã2åã«ããŠå€ãè¡ãšæ°ããè¡ãã³ããŒããŸãã
InsertïŒïŒã¡ãœãã
ãœãŒã¹ã³ãŒã
public StringBuilder Insert(int index, string value) { if (value == null) return this.Insert(index, value, 0); else return this.Insert(index, value, 1); } public StringBuilder Insert(int index, string value, int count) { IntPtr tid; string threadSafeString = this.GetThreadSafeString(out tid); int length = threadSafeString.Length; if (value != null && value.Length != 0) { if (count != 0) { int requiredLength; try { requiredLength = checked (length + value.Length * count);// } catch (OverflowException ex) { throw new OutOfMemoryException(); } if (this.NeedsAllocation(threadSafeString, requiredLength))// { // 2 string newString = this.GetNewString(threadSafeString, requiredLength); newString.InsertInPlace(index, value, count, length, requiredLength);// this.ReplaceString(tid, newString);// } else { threadSafeString.InsertInPlace(index, value, count, length, requiredLength); this.ReplaceString(tid, threadSafeString); } return this; } } return this; }
ãã®ã¡ãœããã¯ãåã®ã¡ãœãããšåæ§ã«ãçŸåšã®ã€ã³ã¹ã¿ã³ã¹ã«æ°ããè¡ãæ¿å ¥ããã®ã«ååãªã¹ããŒã¹ããããã©ããã確èªããããã«å¿ããŠãè¡ã®ãµã€ãºã2åã«ãããããµã€ãºå€æŽããã«å ã®è¡ã«æ¿å ¥ããŸãã
ïŒïŒã¡ãœãããåé€
ãœãŒã¹ã³ãŒã
public StringBuilder Remove(int startIndex, int length) { IntPtr tid; string threadSafeString = this.GetThreadSafeString(out tid); int length1 = threadSafeString.Length; // , threadSafeString.RemoveInPlace(startIndex, length, length1); this.ReplaceString(tid, threadSafeString);// return this; }
ãã®ã¡ãœããã¯ãè¡ã®æ®ããå·Šã«ç§»åããããšã«ãããäžèŠãªæåãåé€ããŸãã æåŸã®æåãåé€ããå Žåãå®éã«ã¯äœãã·ããããå¿ èŠã¯ãããŸããããããã£ãŠãæåŸããåé€ããããšã¯ãè¡ã®ä»ã®éšåãããã¯ããã«é«éã§ãã
ToStringïŒïŒã¡ãœãã
ãœãŒã¹ã³ãŒã
public override string ToString() { string str = this.m_StringValue; if (this.m_currentThread != Thread.InternalGetCurrentThread() || 2 * str.Length < str.ArrayLength) return string.InternalCopy(str);// str.ClearPostNullChar(); this.m_currentThread = IntPtr.Zero; return str; // }
ãã®ã¡ãœããã¯ãå®è£ ãããããããã«ãæååã®ã³ããŒãŸãã¯æäœå¯Ÿè±¡ã®æååãè¿ããŸãã ååãšããŠããã®ã¡ãœããã®æåã®åŒã³åºãã¯å ã®æååãžã®ãªã³ã¯ãè¿ããããéåžžã«é«éã§ããããã®åŸã®åŒã³åºãããšã«æååãã³ããŒãããŸãã .NET 2.0ã®StringBuilderã¯ã©ã¹ã¯ããã®ã¡ãœããã®é床ãéèŠããŠããŸãã
äžè¬ã«ã.NET 2.0ã®StringBuilderã¯ã©ã¹ã¯éåžžã«ç°¡åã«å®è£ ãããŸãã å¯å€æååã䜿çšããååãªã¹ããŒã¹ããªãå Žåã¯ãæ°ããæååãäœæããŸãããã®é·ãã¯åã®æååã®2åã§ãã ãã®ãããªé·ãã®2åã®ã·ããªãªã§ã¯ãã¡ã¢ãªãç·åœ¢ã«è€éã«ãªããŸãããããã¯2次ããã1æ¡åªããŠããŸãã ãã ããè¡ã®é·ããé·ãå Žåãããã¯å¹æçã§ã¯ãããŸããã ã¡ãªã¿ã«ãæååã¯ãµã€ãºã倧ããããã倧ããªãªããžã§ã¯ãïŒLOHïŒã®ããŒãã«é 眮ãããããšããããããŸããããããåªããŠããŸãã
.NET 4.0ã®StringBuilder
åè¿°ããããã«ã.NET 4.0ã§ã¯ãStringBuilderã¯ã©ã¹ã®å®è£ ãå€æŽãããŸããã çŸåšãæåãæ ŒçŽããããã«Stringã®ä»£ããã«Char []ã䜿çšãããŠãããã¯ã©ã¹èªäœã¯RopeStringã®ãããªStringBuilderã®ãªã³ã¯ãªã¹ãã§ãã
ãã®å€æŽã®çç±ã¯éåžžã«æçœã§ãããã®ãããªå®è£ ã§ã¯ãã¡ã¢ãªãäžè¶³ããŠãããšãã«ã¡ã¢ãªãåå²ãåœãŠããå¿ èŠã¯ãããŸãããããã¯ä»¥åã®å®è£ ã«åºæã®ãã®ã§ãã ããã¯ãæåŸã®æååãæåã«åœ¢æããå¿ èŠããããããToStringïŒïŒã¡ãœããã®åäœãå°ãé ããªããã³ããŒãäžèŠãªããAppendïŒïŒã¡ãœããã®åäœãéããªãããšãæå³ããŸãã ãã ããããã¯StringBuilderã®äžè¬çãªãŠãŒã¹ã±ãŒã¹ã«é©åããŸããAppendïŒïŒãäœåºŠãåŒã³åºãã次ã«ToStringïŒïŒã1ååŒã³åºããŸãã
.NET 4.0ã®StringBuilderã¯ã©ã¹ã«ã¯ã次ã®ãã£ãŒã«ãããããŸãã
public sealed class StringBuilder : ISerializable { internal const int DefaultCapacity = 16; internal const int MaxChunkSize = 8000; internal char[] m_ChunkChars; <------------------------------------- internal StringBuilder m_ChunkPrevious; <------------------------------------- internal int m_ChunkLength; internal int m_ChunkOffset; internal int m_MaxCapacity; private const string CapacityField = "Capacity"; private const string MaxCapacityField = "m_MaxCapacity"; private const string StringValueField = "m_StringValue"; private const string ThreadIDField = "m_currentThread"; }
m_ChunkChars-ãªã³ã¯ãªã¹ãã®çŸåšã®èŠçŽ ïŒæååïŒã®æåãå«ãé åã
m_ChunkPrevious-ãªã¹ãå ã®åã®èŠçŽ ïŒStringBuilderïŒãžã®ãªã³ã¯ã
m_ChunkLength-çŸåšã®ãªã¹ãé ç®ã®å®éã®é·ãïŒäœ¿çšãããæåæ°ïŒ;
m_ChunkOffset-ã¹ããªã³ã°ã䜿çšããæåã®ç·æ°ïŒè«çé·ïŒã
m_MaxCapacity -StringBuilderã®çŸåšã®ã€ã³ã¹ã¿ã³ã¹ã®æ倧容éã
.NET Framework 4ããã³.NET Framework 4.5ã§ã¯ãStringBuilderã³ã³ã¹ãã©ã¯ã¿ãŒïŒInt32ãInt32ïŒãåŒã³åºããŠStringBuilderãªããžã§ã¯ããã€ã³ã¹ã¿ã³ã¹åãããšãStringBuilderã€ã³ã¹ã¿ã³ã¹ã®é·ããšå®¹éãMaxCapacityããããã£ã®å€ãè¶ ããŠå¢å ããå¯èœæ§ããããŸãã ããã¯ãç¹ã«Appendããã³AppendFormatã¡ãœãããåŒã³åºããšãã«çºçããå¯èœæ§ããããŸãã
MaxChunkSizeãªã¹ãã¢ã€ãã ã®æ倧é·ã¯8000ã§ãããåç¥ã®ããã«ãããã«ã¯çç±ããããŸãã ã¯ã©ã¹éçºè ããã®ã³ã¡ã³ãã¯æ¬¡ã®ãšããã§ãã
確å®ã«ããããã«ããã£ã³ã¯é åã倧ããªãªããžã§ã¯ãããŒãïŒ<85Kãã€ãã40KæåïŒã«å ¥ããªãããã«ããŸãã æ倧ãã£ã³ã¯ãµã€ãºã倧ãããããšãåŒã³åºãããå²ãåœãŠã³ãŒããå°ãªããªããŸãããæªäœ¿çšæåã®ç¡é§ãå¢ããæ¿å ¥/眮æãé ããªããŸãã
倧ããªãªããžã§ã¯ãã®å Žåãæåé åãããŒãã«èœã¡ãªãããã«ããŸãã ãªã¹ãã¢ã€ãã ïŒã¹ã©ã€ã¹ïŒã®æ倧ãµã€ãºã倧ãããããšãå¿ èŠãªã¡ã¢ãªå²ãåœãŠãå°ãªããªããŸããã䜿çšãããªãæåãå€ããªããæ¿å ¥/眮ææäœãé ããªããŸãã
æãäžè¬çã«äœ¿çšãããæ¹æ³ã®å®è£ ãæ€èšããŠãã ããã
AppendïŒïŒã¡ãœãã
ãœãŒã¹ã³ãŒã
public unsafe StringBuilder Append(string value) { if (value != null) { char[] chArray = this.m_ChunkChars; int index = this.m_ChunkLength; int length = value.Length; int num = index + length; if (num < chArray.Length)// { if (length <= 2) { if (length > 0) chArray[index] = value[0]; if (length > 1) chArray[index + 1] = value[1]; } else { fixed (char* smem = value) fixed (char* dmem = &chArray[index]) string.wstrcpy(dmem, smem, length); } this.m_ChunkLength = num; } else this.AppendHelper(value); } return this; } private unsafe void AppendHelper(string value) { fixed (char* chPtr = value) this.Append(chPtr, value.Length); } internal unsafe StringBuilder Append(char* value, int valueCount) { // int num1 = valueCount + this.m_ChunkLength; if (num1 <= this.m_ChunkChars.Length) { StringBuilder.ThreadSafeCopy(value, this.m_ChunkChars, this.m_ChunkLength, valueCount); this.m_ChunkLength = num1; } else { // () int count = this.m_ChunkChars.Length - this.m_ChunkLength; if (count > 0) { StringBuilder.ThreadSafeCopy(value, this.m_ChunkChars, this.m_ChunkLength, count); this.m_ChunkLength = this.m_ChunkChars.Length; } // , int num2 = valueCount - count; this.ExpandByABlock(num2); // () StringBuilder.ThreadSafeCopy(value + count, this.m_ChunkChars, 0, num2); this.m_ChunkLength = num2; } return this; }
AppendïŒïŒã¡ãœããã¯æ¬¡ã®ããã«æ©èœããŸãïŒçŸåšã®ãªã¹ãèŠçŽ ã«æ°ããè¡ãæ¿å ¥ããã®ã«ååãªæåãããå Žåããã®è¡ã«ã³ããŒãããŸã;ããã§ãªãå Žåãé 眮ãããéšåãã³ããŒãããé©åããªããã®ã«ã€ããŠã¯ãæ°ãããªã¹ãèŠçŽ ãäœæãããŸãïŒ StringBuilder-aïŒã®ã€ã³ã¹ã¿ã³ã¹ãé åã®é·ãã¯ããœãŒã¹æååå šäœã®é·ããšæ®ãã®æååã®é·ãã®ããããé·ãæ¹ã«çãããªããŸãã ãã ããåè¿°ã®ããã«ãé åã®æ倧é·ã¯8000ã§ãã
äžè¬ã«ãæ°ãããªã¹ãã¢ã€ãã ã®é·ããèšç®ããåŒã¯æ¬¡ã®ããã«ãªããŸãã
int length = Math.Max(minBlockCharCount, Math.Min(this.Length, 8000))
ããã§ãminBlockCharCountã¯ãçŸåšã®ã€ã³ã¹ã¿ã³ã¹ã«é 眮ãããŠããéšåãã³ããŒããåŸã®è¡ã®æ®ãã®é·ãã§ãã
ãããã£ãŠããã®ãããªã³ãŒãã®æäœã®çµæãšããŠ
StringBuilder s = new StringBuilder (); for (int i = 0; i < 10000; i++) { s.Append ("T"); }
ãªã¹ãé ç®ã®é åã®é·ãã¯ã8000ã4092ã2048ã1024ã512ã256ã128ã64ã32ã16ã16ã«çãããªããŸãã
ãã®ãããªé·ãã®é åã§ã¯ããªã¹ãã®èŠçŽ ãå€ããªãããããœãŒã¹æååã®ç¹å®ã®æåã«ã¢ã¯ã»ã¹ããæäœã¯ã»ãšãã©OïŒ1ïŒã§éåžžã«è¿ éã«å®è¡ãããŸãã
InsertïŒïŒã¡ãœãã
ãœãŒã¹ã³ãŒã
public unsafe StringBuilder Insert(int index, string value) { if (value != null) { fixed (char* chPtr = value) this.Insert(index, chPtr, value.Length); } return this; } private unsafe void Insert(int index, char* value, int valueCount) { if (valueCount <= 0) return; StringBuilder chunk; int indexInChunk; // (StringBuilder) this.MakeRoom(index, valueCount, out chunk, out indexInChunk, false); this.ReplaceInPlaceAtChunk(ref chunk, ref indexInChunk, value, valueCount); }
InsertïŒïŒã¡ãœããã¯æ¬¡ã®ããã«æ©èœããŸããçŸåšã®ãªã¹ãé ç®ïŒStringBuilderïŒã«æ¿å ¥ããã®ã«ååãªã¹ããŒã¹ãããå Žåãæ¢åã®æåã¯æ°ããããã¹ãã«é 眮ããããã«ã·ãããããŸãã ãã以å€ã®å Žåã¯ãæ°ãããªã¹ãã¢ã€ãã ïŒStringBuilderïŒãäœæãããåã®ã¢ã€ãã ã®æåã®ãã¡ãåãŸããªãéšåãã³ããŒãããŸãã åŸç¶ã®æåã¯å·Šã«ã·ããããŸããã
ãã®ãããªã³ãŒãã®çµæã¯ã©ããªããŸããïŒ
StringBuilder s = new StringBuilder (); for (int i = 0; i < 10000; i++) { s.Insert (0, "T"); }
çµæã¯AppendïŒïŒã䜿çšããã³ãŒããšã¯ç°ãªããéåžžã«æ·±å»ã§ãïŒ
åèŠçŽ ã®StringBuilderã®éåžžã«å€§ããªãªã¹ããååŸããŸããããã¯16æåã®é·ãã«ãªããŸãã ãã®çµæãã€ã³ããã¯ã¹ã«ãã£ãŠç¹å®ã®æåã«ã¢ã¯ã»ã¹ããæäœã¯ãäºæ³ãããé ãå®è¡ãããŸããã€ãŸãããªã¹ãã®é·ããã€ãŸãOïŒnïŒã«æ¯äŸããŸãã
ïŒïŒã¡ãœãããåé€
ãœãŒã¹ã³ãŒã
public StringBuilder Remove(int startIndex, int length) { if (this.Length == length && startIndex == 0) { // . . this.Length = 0; return this; } else { if (length > 0) { StringBuilder chunk; int indexInChunk; this.Remove(startIndex, length, out chunk, out indexInChunk); } return this; } } private void Remove(int startIndex, int count, out StringBuilder chunk, out int indexInChunk) { int num = startIndex + count; // () . chunk = this; StringBuilder stringBuilder = (StringBuilder) null; int sourceIndex = 0; while (true) { if (num - chunk.m_ChunkOffset >= 0) { if (stringBuilder == null) { stringBuilder = chunk; sourceIndex = num - stringBuilder.m_ChunkOffset; } if (startIndex - chunk.m_ChunkOffset >= 0) break; } else chunk.m_ChunkOffset -= count; chunk = chunk.m_ChunkPrevious; } indexInChunk = startIndex - chunk.m_ChunkOffset; int destinationIndex = indexInChunk; int count1 = stringBuilder.m_ChunkLength - sourceIndex; // if (stringBuilder != chunk) { destinationIndex = 0; // startIndex () chunk.m_ChunkLength = indexInChunk; // . stringBuilder.m_ChunkPrevious = chunk; stringBuilder.m_ChunkOffset = chunk.m_ChunkOffset + chunk.m_ChunkLength; // () if (indexInChunk == 0) { stringBuilder.m_ChunkPrevious = chunk.m_ChunkPrevious; chunk = stringBuilder; } } stringBuilder.m_ChunkLength -= sourceIndex - destinationIndex; if (destinationIndex == sourceIndex) // return; // StringBuilder.ThreadSafeCopy(stringBuilder.m_ChunkChars, sourceIndex, stringBuilder.m_ChunkChars, destinationIndex, count1); }
ãã®ã¡ãœããã®å®è£ ã¯ã¯ããã«è€éã«ãªããŸããã ãã ãã以åã®å®è£ ã§ã¯å€æ°ã®æåãã³ããŒãããå·Šã«ã·ãããããŠããŸããã ããã§ã¯ããªã¹ãå ã®1ã€ã®èŠçŽ ïŒStringBuilderïŒã®å¶éå ã§ã®ã¿ãªãã»ãããçæããå¿ èŠããããŸãã
ToStringïŒïŒã¡ãœãã
ãœãŒã¹ã³ãŒã
public override unsafe string ToString() { if (this.Length == 0) return string.Empty; string str = string.FastAllocateString(this.Length); StringBuilder stringBuilder = this; fixed (char* chPtr = str) { do { if (stringBuilder.m_ChunkLength > 0) { char[] chArray = stringBuilder.m_ChunkChars; int num = stringBuilder.m_ChunkOffset; int charCount = stringBuilder.m_ChunkLength; fixed (char* smem = chArray) string.wstrcpy(chPtr + num, smem, charCount); } stringBuilder = stringBuilder.m_ChunkPrevious; } while (stringBuilder != null); } return str; }
ãã®ã¡ãœããã¯ãStringBuilderã®ãªã³ã¯ãªã¹ãå šäœãééãããªã¹ãã®åèŠçŽ ã®æåãçµæã®æååã«é çªã«ã³ããŒããŸãã
æ§èœæ¯èŒ
ããããæãèå³æ·±ãéšåã¯ãã¯ã©ã¹ã®2ã€ã®ããŒãžã§ã³éã®ããã©ãŒãã³ã¹ã®æ¯èŒã§ãã
ãã¹ã1.æå®ãããé·ãã®æååãä¿åããããã«å¿ èŠãªã¡ã¢ãªéã
ã芧ã®ãšãããæååã®é·ããçããšãæ°ããå®è£ ã¯å€ããã®ã倱ããŸãã ãªã¹ãïŒStringBuilderïŒã®åèŠçŽ ã«ã€ããŠãé·ãã容éããªãŒããŒãããæåã®é åã®è¡ã®å é ããã®ãªãã»ãã+ã«é¢ããæ å ±ãå¿ èŠã§ãããããããã¯ç解ã§ããŸãã ããããè¡ã®é·ãã16384ãè¶ ãããšããã«ãå€ãå®è£ ã¯å€±ããå§ããŸãïŒè¡ã®ãµã€ãºã2åã«ãªããããå€ãã®æªäœ¿çšæåãå«ãŸããŸãïŒã
ãã¹ã2. AppendïŒïŒã¡ãœãã
ãããããããã¯æ°ããå®è£ ãåã€ãŸãã«ãã®æ¹æ³ã§ãã ååãªã¡ã¢ãªããªããšãã«æååã®é·ãã2åã«ããŠæååãã³ããŒããå¿ èŠããªããªã£ãããããã®ã¡ãœããã¯ã»ãŒ2åïŒããæ£ç¢ºã«ã¯1.8åïŒéãå®è¡ãããŸãã
ãã¹ã3. InsertïŒïŒã¡ãœãã
ãã§ã«1000æåã®æåã§æºããããæååã«æ¿å ¥ããŸãã
1.è¡ã®å é ã«æ¿å ¥
2.è¡ã®äžå€®ã«æ¿å ¥ããŸã
3.è¡æ«ã«æ¿å ¥
ã³ã¡ã³ãã¯äžèŠã§ã-ã©ãã«è²Œãä»ããŠãæ°ããå®è£ ã¯å€±ãããŸãã
ãã¹ã4. RemoveïŒïŒã¡ãœãã
ãã§ã«æåã§åããããŠããæååããã䜿ãæãããŸã§10æåãåé€ããŸãã
æ°ããå®è£ ã¯ãã»ãšãã©ãã¹ãŠã®å Žæããåé€ããããšãã«åã¡ãŸããããã¯ãæ®ãã®è¡ã®æåãå·Šã«ã·ããããå¿ èŠããªãããã§ãïŒããæ£ç¢ºã«ã¯ãå¿ èŠã§ããã以åã»ã©é »ç¹ã§ã¯ãããŸããïŒã
ãã¹ã5.ã¡ãœããToStringïŒïŒ
åè¿°ã®ããã«ããã®ã¡ãœããã¯ä»¥åã®å®è£ ã倱ããŸãã 以åã®å®è£ ã§ã¯ãïŒæåââã®åŒã³åºãã§ïŒåäœããè¡ãžã®ãªã³ã¯ã®ã¿ãè¿ãããæ°ããå®è£ ã§ã¯ããªã³ã¯ããããªã¹ãã®åèŠçŽ ããã€ãã¹ããŠãçµæã®è¡ãæççã«åéããå¿ èŠããããŸããã
ãªã¹ãã¯16æåã®é·ãã®å€ãã®èŠçŽ ïŒStringBuildersïŒã§æ§æããããããInsertïŒïŒã¡ãœããã䜿çšããŠæååã圢æãããå Žåãæ°ããå®è£ ã¯éåžžã«é ããªããŸãã
ãã¹ã6.ç¹å®ã®ã€ã³ããã¯ã¹ã®ã¢ãã¬ã¹æå®
StringBuilderããªã³ã¯ãªã¹ãã«ãªã£ãããšãèãããšãç¹å®ã®ã€ã³ããã¯ã¹ã§æååã«ã¢ã¯ã»ã¹ããæäœã¯é«äŸ¡ã«ãªããŸãã ç¹ã«ãInsertã¡ãœããã䜿çšããŠåœ¢æãããå Žåã
ãã¹ã7.å žåçãªã·ããªãªïŒAppendïŒïŒãžã®å€ãã®åŒã³åºãããããŠToStringïŒïŒãžã®åŒã³åºã
ååãšããŠãç¹å®ã®ã·ããªãªã«åŸã£ãŠãã®ã¯ã©ã¹ãæäœããŸããAppendïŒïŒã¡ãœãããžã®è€æ°ã®åŒã³åºããšãããã«ç¶ãToStringïŒïŒãžã®1ã€ã®åŒã³åºãã§ãã ãã®ã¯ã©ã¹ã®å®è£ ã¯ããã®ã·ããªãªã®èšç®ã§æ£ç¢ºã«å€æŽãããŸããã
ãããã«
èŠãŠããããã«ã.NET 2.0ã®StringBuilderã¯ã©ã¹ã¯ToStringïŒïŒã¡ãœããã®é床ã«å¯ŸããŠæé©åãããŸãããã.NET 4.0ã§ã¯AppendïŒïŒã¡ãœããã®é床ã«å¯ŸããŠæé©åãããŸããã AppendïŒïŒã¡ãœããã®æ°ããå®è£ ã¯ã»ãŒ2åé«éã§ãããInsertïŒïŒããã³ToStringïŒïŒã¡ãœããã¯äœéã§ãã ãã ããç¹å®ã®ã·ããªãªã§ãã®ã¯ã©ã¹ãæäœãããããAppendïŒïŒã¡ãœãããè€æ°ååŒã³åºããç¶ããŠToStringïŒïŒã¡ãœããã1ååŒã³åºããšãããã©ãŒãã³ã¹ãåäžããŸãã
AppendïŒïŒã¡ãœãããè€æ°ååŒã³åºãã ãã§ããã©ãŒãã³ã¹ãåäžããã¯ã©ã¹ã®æ°ããå®è£ ãèãããšãã¯ã©ã¹ã¯StringAppenderãšåŒã°ããããã«ãªããŸãã*ïŒ