#眉標=Windows Form #副標=有趣的.NET記憶體管理探索 #大標=StringBuilder與String效能大車拼 #作者=文/圖 李明儒 ==<反灰>=========== public class sample { static void Main() { string s = "Hello" + " " + "World!"; Console.WriteLine(s); } } ================ ==<反灰>=========== Test1=4152ms Test2=6ms Test3=7ms ================ ============= 程式1 靜態字串串接比較 Stopwatch sw = new Stopwatch(); int times = 1000000; sw.Start(); for (int i = 0; i < times; i++) GetSqlString_1(); sw.Stop(); Console.WriteLine(string.Format("Test1={0}ms", sw.ElapsedMilliseconds)); sw.Reset(); sw.Start(); for (int i = 0; i < times; i++) GetSqlString_2(); sw.Stop(); Console.WriteLine(string.Format("Test2={0}ms", sw.ElapsedMilliseconds)); sw.Reset(); sw.Start(); for (int i = 0; i < times; i++) GetSqlString_3(); sw.Stop(); Console.WriteLine(string.Format("Test3={0}ms", sw.ElapsedMilliseconds));================ ====================== 程式2 public class sample { static void Main() { string s = ""; s += "ABC"; s += "123"; return; } }================ ======================= 程式3 .load sos extension C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll loaded !clrstack -l PDB symbol for mscorwks.dll not loaded OS Thread Id: 0x28dc (10460) ESP EIP 003feee4 00520094 sample.Main() LOCALS: = 0x00000000 003ff13c 79e7c74b [GCFrame: 003ff13c] ================ ============= 程式4 !clrstack –l OS Thread Id: 0x28dc (10460) ESP EIP 003feee4 0052009c sample.Main() LOCALS: = 0x015b1574 003ff13c 79e7c74b [GCFrame: 003ff13c] !dumpobj 0x015b1574 Name: System.String MethodTable: 790fd8c4 EEClass: 790fd824 Size: 18(0x12) bytes (C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll) String: Fields: MT Field Offset Type VT Attr Value Name 79102290 4000096 4 System.Int32 1 instance 1 m_arrayLength 79102290 4000097 8 System.Int32 1 instance 0 m_stringLength 790ff328 4000098 c System.Char 1 instance 0 m_firstChar 790fd8c4 4000099 10 System.String 0 shared static Empty >> Domain:Value 005602e8:790d884c << 7912dd40 400009a 14 System.Char[] 0 shared static WhitespaceChars >> Domain:Value 005602e8:015b1440 << ================ ============= 程式5 !clrstack -l OS Thread Id: 0x28dc (10460) ESP EIP 003feee4 005200ad sample.Main() LOCALS: = 0x015c6590 (…略…) !dumpobj 0x015c6590 (省略部分顯示內容) Name: System.String (...略…) Size: 24(0x18) bytes String: ABC Fields: MT Field Offset Type VT Attr Value Name 79102290 4000096 4 System.Int32 1 instance 4 m_arrayLength 79102290 4000097 8 System.Int32 1 instance 3 m_stringLength 790ff328 4000098 c System.Char 1 instance 41 m_firstChar (…略…) ================ ============= 程式6 !clrstack -l (…略…) LOCALS: = 0x015c65c0 !dumpobj 0x015c65c0 Name: System.String (…略…) Size: 30(0x1e) bytes String: ABC123 Fields: MT Field Offset Type VT Attr Value Name 79102290 4000096 4 System.Int32 1 instance 7 m_arrayLength 79102290 4000097 8 System.Int32 1 instance 6 m_stringLength 790ff328 4000098 c System.Char 1 instance 41 m_firstChar ================ ============= 程式7 public class sample { static void Main() { StringBuilder sb = new StringBuilder(); sb.Append("ABCD"); sb.Append("1234"); sb.Append("0123456789"); return; } } ================ ============= 程式8 !clrstack –l (…略…) LOCALS: = 0x013a65f0 !do 0x013a65f0 Name: System.Text.StringBuilder (..略…) Size: 20(0x14) bytes Fields: MT Field Offset Type VT Attr Value Name 791016bc 40000b1 8 System.IntPtr 1 instance 000CB688 m_currentThread 79102290 40000b2 c System.Int32 1 instance 2147483647 m_MaxCapacity 790fd8c4 40000b3 4 System.String 0 instance 013a6604 m_StringValue !do 013a6604 Name: System.String (…略…) Size: 50(0x32) bytes (C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll) String: Fields: MT Field Offset Type VT Attr Value Name 79102290 4000096 4 System.Int32 1 instance 17 m_arrayLength 79102290 4000097 8 System.Int32 1 instance 0 m_stringLength 790ff328 4000098 c System.Char 1 instance 0 m_firstChar ================ ============= 程式9 !do 013a6604 (…略…) String: ABCD Fields: MT Field Offset Type VT Attr Value Name 79102290 4000096 4 System.Int32 1 instance 17 m_arrayLength 79102290 4000097 8 System.Int32 1 instance 4 m_stringLength (…略…) !do 013a6604 (…略…) String: ABCD1234 Fields: MT Field Offset Type VT Attr Value Name 79102290 4000096 4 System.Int32 1 instance 17 m_arrayLength 79102290 4000097 8 System.Int32 1 instance 8 m_stringLength (…略…) ================ ============= 程式10 !do 0x013a65f0 Name: System.Text.StringBuilder (…略…) Size: 20(0x14) bytes Fields: MT Field Offset Type VT Attr Value Name 791016bc 40000b1 8 System.IntPtr 1 instance 00000000 m_currentThread 79102290 40000b2 c System.Int32 1 instance 2147483647 m_MaxCapacity 790fd8c4 40000b3 4 System.String 0 instance 013a6778 m_StringValue (…略…) !do 013a6778 (…略…) Size: 82(0x52) bytes String: ABCD12340123456789 Fields: MT Field Offset Type VT Attr Value Name 79102290 4000096 4 System.Int32 1 instance 33 m_arrayLength 79102290 4000097 8 System.Int32 1 instance 18 m_stringLength (…略…) ================ ======================== 程式11 public class sample { static void test1() { string s = ""; for (int i = 1; i < 1024 * 64; i++) s += "0123456789ABCDEF"; Console.WriteLine(s.Length); } static void test2() { StringBuilder sb = new StringBuilder(); for (int i = 1; i < 1024 * 64; i++) sb.Append("0123456789ABCDEF"); Console.WriteLine(sb.Length); } static void test3() { StringBuilder sb = new StringBuilder(1024 * 1024); for (int i = 1; i < 1024 * 64; i++) sb.Append("0123456789ABCDEF"); Console.WriteLine(sb.Length); } static void Main() { System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); test1(); //or test2(), test3() sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); return; //Break here to !dumpheap -stat } } ================ ============= 程式12 test1() !dumpheap -stat total 6689 objects Statistics: MT Count TotalSize Class Name 791334a8 1 12 System.Collections.Generic.GenericEqualityComparer`1[[System.String, mscorlib]] 79119954 1 12 System.Security.Permissions.ReflectionPermission …略… 004a05d0 14 2097044 Free 790fd8c4 5233 6585276 System.String Total 6689 objects test2() !dumpheap -stat total 6948 objects Statistics: MT Count TotalSize Class Name 791334a8 1 12 System.Collections.Generic.GenericEqualityComparer`1[[System.String, mscorlib]] 79128334 1 12 System.Security.SecurityZone …略… 7912d8f8 394 40076 System.Object[] 790fd8c4 5256 4491280 System.String Total 6948 objects test3() !dumpheap -stat total 6928 objects Statistics: MT Count TotalSize Class Name 791334a8 1 12 System.Collections.Generic.GenericEqualityComparer`1[[System.String, mscorlib]] 79128334 1 12 System.Security.SecurityZone …略… 7912d8f8 394 40076 System.Object[] 790fd8c4 5240 2393824 System.String Total 6928 objects ================    ============= 註解資料 1. 動態字串相加的效能比較:http://www.codeproject.com/KB/cs/stringperf.aspx。 2. @-Quoted String Literals:http://msdn2.microsoft.com/en-us/library/362314fe(VS.71).aspx。 3. SOS指令說明:http://msdn2.microsoft.com/en-us/library/bb190764(VS.80).aspx。 4. .NET記憶體配置概論:http://tinyurl.com/pnyo4。 ================