KEMBAR78
String in .net
STRING IN .NET
Larry Nung
AGENDA
String
String operations
“”& String.Empty
Null & Empty check
String pool
String property
StringBuilder
Reference
Q & A
2
STRING
3
STRING
[SerializableAttribute] [ComVisibleAttribute(true)]
public sealed class String : IComparable,
ICloneable, IConvertible, IComparable<string>,
IEnumerable<char>, IEnumerable,
IEquatable<string>
4
STRING
[SerializableAttribute] [ComVisibleAttribute(true)]
public sealed class String : IComparable,
ICloneable, IConvertible, IComparable<string>,
IEnumerable<char>, IEnumerable,
IEquatable<string>
5
STRING
6
STRING
7
STRING OPERATIONS
8
STRING OPERATIONS
var name = "LevelUp";
var url = "http://larrynung.github.io/";
var str1 = name + " (" + url + ")";
var str2 = string.Concat(name, " (", url, ")");
var str3 = string.Format("{0} ({1})", name, url);
var str4 = @"Blog: LevelUp Url: http://larrynung.github.io/";
var str5 = "c:BlogLevelUp";
var str6 = @"c:BlogLevelUp";
var msg = string.Empty;
msg += String.Format("str1 == str2 => {0}", str1 == str2);
msg += Environment.NewLine;
msg += String.Format("str1.Equals(str3) => {0}", str1.Equals(str3));
msg += Environment.NewLine;
msg += str4;
msg += Environment.NewLine;
msg += str5;
msg += Environment.NewLine;
msg += str6;
msg += Environment.NewLine; Console.WriteLine(msg);
9
“”& STRING.EMPTY
10
“” & STRING.EMPTY
11
“” & STRING.EMPTY
static void Main(string[] args) {
int count = 1000000000;
EmptyString1(count); EmptyString2(count); EmptyString3(count);
}
private static void EmptyString1(int count) {
String test; Stopwatch sw = Stopwatch.StartNew();
for (int idx = 0; idx < count; ++idx) { test = ""; }
sw.Stop();
Console.WriteLine("EmptyString1: " + sw.ElapsedMilliseconds.ToString());
}
private static void EmptyString2(int count) {
String test; Stopwatch sw = Stopwatch.StartNew();
for (int idx = 0; idx < count; ++idx) { test = string.Empty; }
sw.Stop();
Console.WriteLine("EmptyString2: " + sw.ElapsedMilliseconds.ToString());
}
private static void EmptyString3(int count) {
String test; Stopwatch sw = Stopwatch.StartNew();
for (int idx = 0; idx < count; ++idx) { test = new String(' ',0); }
sw.Stop();
Console.WriteLine("EmptyString3: " + sw.ElapsedMilliseconds.ToString());
}
12
“” & STRING.EMPTY
static void Main(string[] args) {
int count = 1000000000;
EmptyString1(count); EmptyString2(count); EmptyString3(count);
}
private static void EmptyString1(int count) {
String test; Stopwatch sw = Stopwatch.StartNew();
for (int idx = 0; idx < count; ++idx) { test = ""; }
sw.Stop();
Console.WriteLine("EmptyString1: " + sw.ElapsedMilliseconds.ToString());
}
private static void EmptyString2(int count) {
String test; Stopwatch sw = Stopwatch.StartNew();
for (int idx = 0; idx < count; ++idx) { test = string.Empty; }
sw.Stop();
Console.WriteLine("EmptyString2: " + sw.ElapsedMilliseconds.ToString());
}
private static void EmptyString3(int count) {
String test; Stopwatch sw = Stopwatch.StartNew();
for (int idx = 0; idx < count; ++idx) { test = new String(' ',0); }
sw.Stop();
Console.WriteLine("EmptyString3: " + sw.ElapsedMilliseconds.ToString());
}
130
1000
2000
3000
4000
5000
6000
7000
1000000 10000000 1000000000
""
String.Empty
new String()
“” & STRING.EMPTY
static void Main(string[] args) {
int count = 1000000000;
EmptyString1(count); EmptyString2(count); EmptyString3(count);
}
private static void EmptyString1(int count) {
String test; Stopwatch sw = Stopwatch.StartNew();
for (int idx = 0; idx < count; ++idx) { test = ""; }
sw.Stop();
Console.WriteLine("EmptyString1: " + sw.ElapsedMilliseconds.ToString());
}
private static void EmptyString2(int count) {
String test; Stopwatch sw = Stopwatch.StartNew();
for (int idx = 0; idx < count; ++idx) { test = string.Empty; }
sw.Stop();
Console.WriteLine("EmptyString2: " + sw.ElapsedMilliseconds.ToString());
}
private static void EmptyString3(int count) {
String test; Stopwatch sw = Stopwatch.StartNew();
for (int idx = 0; idx < count; ++idx) { test = new String(' ',0); }
sw.Stop();
Console.WriteLine("EmptyString3: " + sw.ElapsedMilliseconds.ToString());
}
140
1000
2000
3000
4000
5000
6000
7000
1000000 10000000 1000000000
""
String.Empty
new String()
NULL & EMPTY CHECK
15
NULL & EMPTY CHECK
 Check with == null
 e.x. if (str == nill)
 Check with == ""
 e.x. if (str == “”)
 Check with == String.Empty
 e.x. if (str == String.Empty)
 Check with String.IsNullOrEmpty(str)
 e.x. if (String.IsNullOrEmpty(str))
 Check with String.Length == 0
 e.x. if (str.Length == 0)
16
NULL & EMPTY CHECK
private static void Main(string[] args) {
string[] testStrings = new string[] { null, "", string.Empty };
foreach (string str in testStrings) {
TestString(str);
Console.WriteLine("=======================");
}
}
private static void TestString(string str) {
if (str == null)
Console.WriteLine("str = null");
if (str == "")
Console.WriteLine("str = """);
if (str == string.Empty)
Console.WriteLine("str = String.Empty");
if (string.IsNullOrEmpty(str))
Console.WriteLine("String.IsNullOrEmpty(str)");
try {
if (str.Length == 0) Console.WriteLine("str.Length = 0");
} catch (Exception ex) { }
}
17
NULL & EMPTY CHECK
private static void Main(string[] args) {
string[] testStrings = new string[] { null, "", string.Empty };
foreach (string str in testStrings) {
TestString(str);
Console.WriteLine("=======================");
}
}
private static void TestString(string str) {
var count = 100000000;
Console.WriteLine("str == null: {0} ms",
DoTest(count, () => { var result = str == null; }));
Console.WriteLine("str == "": {0} ms",
DoTest(count, () => { var result = str == ""; }));
Console.WriteLine("str == String.Empty: {0} ms",
DoTest(count, () => { var result = str == String.Empty; }));
Console.WriteLine("string.IsNullOrEmpty(str): {0} ms",
DoTest(count, () => { var result = string.IsNullOrEmpty(str); }));
try {
Console.WriteLine("str.Length == 0: {0} ms",
DoTest(count, () => { var result = str.Length == 0; }));
} catch { }
}
static long DoTest(int count, Action action)
{
var sw = Stopwatch.StartNew();
for (int i = 0; i < count; ++i) action();
return sw.ElapsedMilliseconds;
}
18
NULL & EMPTY CHECK
private static void Main(string[] args) {
string[] testStrings = new string[] { null, "", string.Empty };
foreach (string str in testStrings) {
TestString(str);
Console.WriteLine("=======================");
}
}
private static void TestString(string str) {
var count = 100000000;
Console.WriteLine("str == null: {0} ms",
DoTest(count, () => { var result = str == null; }));
Console.WriteLine("str == "": {0} ms",
DoTest(count, () => { var result = str == ""; }));
Console.WriteLine("str == String.Empty: {0} ms",
DoTest(count, () => { var result = str == String.Empty; }));
Console.WriteLine("string.IsNullOrEmpty(str): {0} ms",
DoTest(count, () => { var result = string.IsNullOrEmpty(str); }));
try {
Console.WriteLine("str.Length == 0: {0} ms",
DoTest(count, () => { var result = str.Length == 0; }));
} catch { }
}
static long DoTest(int count, Action action)
{
var sw = Stopwatch.StartNew();
for (int i = 0; i < count; ++i) action();
return sw.ElapsedMilliseconds;
}
19
STRING POOL
20
STRING POOL
var str1 = "aaaa";
var str2 = "aa" + "aa";
var str3 = "aa"; str3 += str3;
var str4 = new string('a', 4);
var str5 = string.Intern(str4);
Debug.WriteLine(ReferenceEquals(str1, str2));
Debug.WriteLine(ReferenceEquals(str1, str3));
Debug.WriteLine(ReferenceEquals(str1, str4));
Debug.WriteLine(ReferenceEquals(str1, str5));
21
STRING POOL
var str1 = "aaaa";
var str2 = "aa" + "aa";
var str3 = "aa"; str3 += str3;
var str4 = new string('a', 4);
var str5 = string.Intern(str4);
Debug.WriteLine(ReferenceEquals(str1, str2));
Debug.WriteLine(ReferenceEquals(str1, str3));
Debug.WriteLine(ReferenceEquals(str1, str4));
Debug.WriteLine(ReferenceEquals(str1, str5));
22
STRING POOL
var str1 = "aaaa";
var str2 = "aa" + "aa";
var str3 = "aa"; str3 += str3;
var str4 = new string('a', 4);
var str5 = string.Intern(str4);
Debug.WriteLine(ReferenceEquals(str1, str2));
Debug.WriteLine(ReferenceEquals(str1, str3));
Debug.WriteLine(ReferenceEquals(str1, str4));
Debug.WriteLine(ReferenceEquals(str1, str5));
23
str1
str2
str3
str4
“aaaa”
“aaaa”
str5 “aaaa”
String Pool
STRING PROPERTY
24
STRING PROPERTY
internal class Program
{
public String Name { get; set; }
}
25
STRING PROPERTY
internal class Program
{
public String Name { get; set; }
}
26
STRING PROPERTY
internal class Program
{
public String Name { get; set; }
}
27
STRING PROPERTY
internal class Program
{
private String _name;
public String Name
{
get { return _name ?? String.Empty; }
set { _name = value; }
}
}
28
STRINGBUILDER
29
STRINGBUILDER
 Consider using the String class under these conditions:
 When the number of changes that your app will make to a
string is small. In these cases, StringBuilder might offer
negligible or no performance improvement over String.
 When you are performing a fixed number of concatenation
operations, particularly with string literals. In this case, the
compiler might combine the concatenation operations into a
single operation.
 When you have to perform extensive search operations while
you are building your string. The StringBuilder class lacks
search methods such as IndexOf or StartsWith. You'll have to
convert the StringBuilderobject to a String for these
operations, and this can negate the performance benefit from
using StringBuilder. For more information, see the Searching
the text in a StringBuilder object section.
30
STRINGBUILDER
 Consider using the StringBuilder class under these
conditions:
 When you expect your app to make an unknown
number of changes to a string at design time (for
example, when you are using a loop to concatenate a
random number of strings that contain user input).
 When you expect your app to make a significant
number of changes to a string.
31
STRINGBUILDER
var count = 1000000;
var result = string.Empty;
var sw = Stopwatch.StartNew();
for (var index = 0; index < count; ++index)
result += "a";
Console.WriteLine(sw.ElapsedMilliseconds);
result = string.Empty;
sw.Restart();
var sb = new StringBuilder();
for (var index = 0; index < count; ++index)
sb.Append("a");
result = sb.ToString();
Console.WriteLine(sw.ElapsedMilliseconds);
32
0
50000
100000
150000
200000
250000
300000
350000
1000 10000 100000 1000000
String concat
StringBuilder
“aaaa”
164
“aaaaaaaaaaaaaaaa”
16
“aaaaaaaaaaaaaaaaa”
3217
“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa”
6433
REFERENCE
33
REFERENCE
 [.Net Concept]理解並善用String pool - Level Up- 點
部落
 http://www.dotblogs.com.tw/larrynung/archive/2011/06/3
0/30763.aspx
 [Performance][C#]String.Empty V.S “” - Level Up-
點部落
 http://www.dotblogs.com.tw/larrynung/archive/2009/12/2
2/12615.aspx
 [Performance][VB.NET].NET空字串判斷徹底研究 -
Level Up- 點部落
 http://www.dotblogs.com.tw/larrynung/archive/2009/03/1
3/7461.aspx 34
REFERENCE
 [.NET Concept]集合與字串類型的屬性和方法應避免
回傳null - Level Up- 點部落
 http://www.dotblogs.com.tw/larrynung/archive/2011/04/1
6/22866.aspx
 String與Stringbuilder組字串的效能比較 - Jeff 隨手記
- 點部落
 http://www.dotblogs.com.tw/jeff-
yeh/archive/2008/11/04/5870.aspx
 [C#.NET] 動態處理字串 - StringBuilder 類別 與
String 類別的效能 - 余小章 @ 大內殿堂- 點部落
 http://www.dotblogs.com.tw/yc421206/archive/2010/10/
26/18575.aspx 35
REFERENCE
 StringBuilder串接字串的迷思 - 黑暗執行緒
 http://blog.darkthread.net/blogs/darkthreadtw/archive/20
07/12/15/stringbuilder-for-static-string-concate.aspx
 Heikniemi Hardcoded » .net String vs.
StringBuilder – concatenation performance
 http://www.heikniemi.net/hardcoded/2004/08/net-string-
vs-stringbuilder-concatenation-performance/
 StringBuilder Class (System.Text)
 https://msdn.microsoft.com/en-
us//library/system.text.stringbuilder.aspx
36
REFERENCE
 文章-StringBuilder與String的字串相接效能大車拼 -
黑暗執行緒
 http://blog.darkthread.net/blogs/darkthreadtw/archive/20
09/09/07/article-stringbuilder-vs-string.aspx
 Performance considerations for strings in C# -
CodeProject
 http://www.codeproject.com/Articles/10318/Performance
-considerations-for-strings-in-C
 Improving String Handling Performance in .NET
Framework Applications
 https://msdn.microsoft.com/en-
us/library/aa302329.aspx?f=255&MSPPError=-
2147217396
37
REFERENCE
 Introduction to Programming with C# / Java Books
» Chapter 13. Strings and Text Processing
 http://www.introprogramming.info/english-intro-csharp-
book/read-online/chapter-13-strings-and-text-
processing/
38
Q&A
39
QUESTION & ANSWER
40

String in .net

  • 1.
  • 2.
    AGENDA String String operations “”& String.Empty Null& Empty check String pool String property StringBuilder Reference Q & A 2
  • 3.
  • 4.
    STRING [SerializableAttribute] [ComVisibleAttribute(true)] public sealedclass String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string> 4
  • 5.
    STRING [SerializableAttribute] [ComVisibleAttribute(true)] public sealedclass String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string> 5
  • 6.
  • 7.
  • 8.
  • 9.
    STRING OPERATIONS var name= "LevelUp"; var url = "http://larrynung.github.io/"; var str1 = name + " (" + url + ")"; var str2 = string.Concat(name, " (", url, ")"); var str3 = string.Format("{0} ({1})", name, url); var str4 = @"Blog: LevelUp Url: http://larrynung.github.io/"; var str5 = "c:BlogLevelUp"; var str6 = @"c:BlogLevelUp"; var msg = string.Empty; msg += String.Format("str1 == str2 => {0}", str1 == str2); msg += Environment.NewLine; msg += String.Format("str1.Equals(str3) => {0}", str1.Equals(str3)); msg += Environment.NewLine; msg += str4; msg += Environment.NewLine; msg += str5; msg += Environment.NewLine; msg += str6; msg += Environment.NewLine; Console.WriteLine(msg); 9
  • 10.
  • 11.
  • 12.
    “” & STRING.EMPTY staticvoid Main(string[] args) { int count = 1000000000; EmptyString1(count); EmptyString2(count); EmptyString3(count); } private static void EmptyString1(int count) { String test; Stopwatch sw = Stopwatch.StartNew(); for (int idx = 0; idx < count; ++idx) { test = ""; } sw.Stop(); Console.WriteLine("EmptyString1: " + sw.ElapsedMilliseconds.ToString()); } private static void EmptyString2(int count) { String test; Stopwatch sw = Stopwatch.StartNew(); for (int idx = 0; idx < count; ++idx) { test = string.Empty; } sw.Stop(); Console.WriteLine("EmptyString2: " + sw.ElapsedMilliseconds.ToString()); } private static void EmptyString3(int count) { String test; Stopwatch sw = Stopwatch.StartNew(); for (int idx = 0; idx < count; ++idx) { test = new String(' ',0); } sw.Stop(); Console.WriteLine("EmptyString3: " + sw.ElapsedMilliseconds.ToString()); } 12
  • 13.
    “” & STRING.EMPTY staticvoid Main(string[] args) { int count = 1000000000; EmptyString1(count); EmptyString2(count); EmptyString3(count); } private static void EmptyString1(int count) { String test; Stopwatch sw = Stopwatch.StartNew(); for (int idx = 0; idx < count; ++idx) { test = ""; } sw.Stop(); Console.WriteLine("EmptyString1: " + sw.ElapsedMilliseconds.ToString()); } private static void EmptyString2(int count) { String test; Stopwatch sw = Stopwatch.StartNew(); for (int idx = 0; idx < count; ++idx) { test = string.Empty; } sw.Stop(); Console.WriteLine("EmptyString2: " + sw.ElapsedMilliseconds.ToString()); } private static void EmptyString3(int count) { String test; Stopwatch sw = Stopwatch.StartNew(); for (int idx = 0; idx < count; ++idx) { test = new String(' ',0); } sw.Stop(); Console.WriteLine("EmptyString3: " + sw.ElapsedMilliseconds.ToString()); } 130 1000 2000 3000 4000 5000 6000 7000 1000000 10000000 1000000000 "" String.Empty new String()
  • 14.
    “” & STRING.EMPTY staticvoid Main(string[] args) { int count = 1000000000; EmptyString1(count); EmptyString2(count); EmptyString3(count); } private static void EmptyString1(int count) { String test; Stopwatch sw = Stopwatch.StartNew(); for (int idx = 0; idx < count; ++idx) { test = ""; } sw.Stop(); Console.WriteLine("EmptyString1: " + sw.ElapsedMilliseconds.ToString()); } private static void EmptyString2(int count) { String test; Stopwatch sw = Stopwatch.StartNew(); for (int idx = 0; idx < count; ++idx) { test = string.Empty; } sw.Stop(); Console.WriteLine("EmptyString2: " + sw.ElapsedMilliseconds.ToString()); } private static void EmptyString3(int count) { String test; Stopwatch sw = Stopwatch.StartNew(); for (int idx = 0; idx < count; ++idx) { test = new String(' ',0); } sw.Stop(); Console.WriteLine("EmptyString3: " + sw.ElapsedMilliseconds.ToString()); } 140 1000 2000 3000 4000 5000 6000 7000 1000000 10000000 1000000000 "" String.Empty new String()
  • 15.
    NULL & EMPTYCHECK 15
  • 16.
    NULL & EMPTYCHECK  Check with == null  e.x. if (str == nill)  Check with == ""  e.x. if (str == “”)  Check with == String.Empty  e.x. if (str == String.Empty)  Check with String.IsNullOrEmpty(str)  e.x. if (String.IsNullOrEmpty(str))  Check with String.Length == 0  e.x. if (str.Length == 0) 16
  • 17.
    NULL & EMPTYCHECK private static void Main(string[] args) { string[] testStrings = new string[] { null, "", string.Empty }; foreach (string str in testStrings) { TestString(str); Console.WriteLine("======================="); } } private static void TestString(string str) { if (str == null) Console.WriteLine("str = null"); if (str == "") Console.WriteLine("str = """); if (str == string.Empty) Console.WriteLine("str = String.Empty"); if (string.IsNullOrEmpty(str)) Console.WriteLine("String.IsNullOrEmpty(str)"); try { if (str.Length == 0) Console.WriteLine("str.Length = 0"); } catch (Exception ex) { } } 17
  • 18.
    NULL & EMPTYCHECK private static void Main(string[] args) { string[] testStrings = new string[] { null, "", string.Empty }; foreach (string str in testStrings) { TestString(str); Console.WriteLine("======================="); } } private static void TestString(string str) { var count = 100000000; Console.WriteLine("str == null: {0} ms", DoTest(count, () => { var result = str == null; })); Console.WriteLine("str == "": {0} ms", DoTest(count, () => { var result = str == ""; })); Console.WriteLine("str == String.Empty: {0} ms", DoTest(count, () => { var result = str == String.Empty; })); Console.WriteLine("string.IsNullOrEmpty(str): {0} ms", DoTest(count, () => { var result = string.IsNullOrEmpty(str); })); try { Console.WriteLine("str.Length == 0: {0} ms", DoTest(count, () => { var result = str.Length == 0; })); } catch { } } static long DoTest(int count, Action action) { var sw = Stopwatch.StartNew(); for (int i = 0; i < count; ++i) action(); return sw.ElapsedMilliseconds; } 18
  • 19.
    NULL & EMPTYCHECK private static void Main(string[] args) { string[] testStrings = new string[] { null, "", string.Empty }; foreach (string str in testStrings) { TestString(str); Console.WriteLine("======================="); } } private static void TestString(string str) { var count = 100000000; Console.WriteLine("str == null: {0} ms", DoTest(count, () => { var result = str == null; })); Console.WriteLine("str == "": {0} ms", DoTest(count, () => { var result = str == ""; })); Console.WriteLine("str == String.Empty: {0} ms", DoTest(count, () => { var result = str == String.Empty; })); Console.WriteLine("string.IsNullOrEmpty(str): {0} ms", DoTest(count, () => { var result = string.IsNullOrEmpty(str); })); try { Console.WriteLine("str.Length == 0: {0} ms", DoTest(count, () => { var result = str.Length == 0; })); } catch { } } static long DoTest(int count, Action action) { var sw = Stopwatch.StartNew(); for (int i = 0; i < count; ++i) action(); return sw.ElapsedMilliseconds; } 19
  • 20.
  • 21.
    STRING POOL var str1= "aaaa"; var str2 = "aa" + "aa"; var str3 = "aa"; str3 += str3; var str4 = new string('a', 4); var str5 = string.Intern(str4); Debug.WriteLine(ReferenceEquals(str1, str2)); Debug.WriteLine(ReferenceEquals(str1, str3)); Debug.WriteLine(ReferenceEquals(str1, str4)); Debug.WriteLine(ReferenceEquals(str1, str5)); 21
  • 22.
    STRING POOL var str1= "aaaa"; var str2 = "aa" + "aa"; var str3 = "aa"; str3 += str3; var str4 = new string('a', 4); var str5 = string.Intern(str4); Debug.WriteLine(ReferenceEquals(str1, str2)); Debug.WriteLine(ReferenceEquals(str1, str3)); Debug.WriteLine(ReferenceEquals(str1, str4)); Debug.WriteLine(ReferenceEquals(str1, str5)); 22
  • 23.
    STRING POOL var str1= "aaaa"; var str2 = "aa" + "aa"; var str3 = "aa"; str3 += str3; var str4 = new string('a', 4); var str5 = string.Intern(str4); Debug.WriteLine(ReferenceEquals(str1, str2)); Debug.WriteLine(ReferenceEquals(str1, str3)); Debug.WriteLine(ReferenceEquals(str1, str4)); Debug.WriteLine(ReferenceEquals(str1, str5)); 23 str1 str2 str3 str4 “aaaa” “aaaa” str5 “aaaa” String Pool
  • 24.
  • 25.
    STRING PROPERTY internal classProgram { public String Name { get; set; } } 25
  • 26.
    STRING PROPERTY internal classProgram { public String Name { get; set; } } 26
  • 27.
    STRING PROPERTY internal classProgram { public String Name { get; set; } } 27
  • 28.
    STRING PROPERTY internal classProgram { private String _name; public String Name { get { return _name ?? String.Empty; } set { _name = value; } } } 28
  • 29.
  • 30.
    STRINGBUILDER  Consider usingthe String class under these conditions:  When the number of changes that your app will make to a string is small. In these cases, StringBuilder might offer negligible or no performance improvement over String.  When you are performing a fixed number of concatenation operations, particularly with string literals. In this case, the compiler might combine the concatenation operations into a single operation.  When you have to perform extensive search operations while you are building your string. The StringBuilder class lacks search methods such as IndexOf or StartsWith. You'll have to convert the StringBuilderobject to a String for these operations, and this can negate the performance benefit from using StringBuilder. For more information, see the Searching the text in a StringBuilder object section. 30
  • 31.
    STRINGBUILDER  Consider usingthe StringBuilder class under these conditions:  When you expect your app to make an unknown number of changes to a string at design time (for example, when you are using a loop to concatenate a random number of strings that contain user input).  When you expect your app to make a significant number of changes to a string. 31
  • 32.
    STRINGBUILDER var count =1000000; var result = string.Empty; var sw = Stopwatch.StartNew(); for (var index = 0; index < count; ++index) result += "a"; Console.WriteLine(sw.ElapsedMilliseconds); result = string.Empty; sw.Restart(); var sb = new StringBuilder(); for (var index = 0; index < count; ++index) sb.Append("a"); result = sb.ToString(); Console.WriteLine(sw.ElapsedMilliseconds); 32 0 50000 100000 150000 200000 250000 300000 350000 1000 10000 100000 1000000 String concat StringBuilder “aaaa” 164 “aaaaaaaaaaaaaaaa” 16 “aaaaaaaaaaaaaaaaa” 3217 “aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa” 6433
  • 33.
  • 34.
    REFERENCE  [.Net Concept]理解並善用Stringpool - Level Up- 點 部落  http://www.dotblogs.com.tw/larrynung/archive/2011/06/3 0/30763.aspx  [Performance][C#]String.Empty V.S “” - Level Up- 點部落  http://www.dotblogs.com.tw/larrynung/archive/2009/12/2 2/12615.aspx  [Performance][VB.NET].NET空字串判斷徹底研究 - Level Up- 點部落  http://www.dotblogs.com.tw/larrynung/archive/2009/03/1 3/7461.aspx 34
  • 35.
    REFERENCE  [.NET Concept]集合與字串類型的屬性和方法應避免 回傳null- Level Up- 點部落  http://www.dotblogs.com.tw/larrynung/archive/2011/04/1 6/22866.aspx  String與Stringbuilder組字串的效能比較 - Jeff 隨手記 - 點部落  http://www.dotblogs.com.tw/jeff- yeh/archive/2008/11/04/5870.aspx  [C#.NET] 動態處理字串 - StringBuilder 類別 與 String 類別的效能 - 余小章 @ 大內殿堂- 點部落  http://www.dotblogs.com.tw/yc421206/archive/2010/10/ 26/18575.aspx 35
  • 36.
    REFERENCE  StringBuilder串接字串的迷思 -黑暗執行緒  http://blog.darkthread.net/blogs/darkthreadtw/archive/20 07/12/15/stringbuilder-for-static-string-concate.aspx  Heikniemi Hardcoded » .net String vs. StringBuilder – concatenation performance  http://www.heikniemi.net/hardcoded/2004/08/net-string- vs-stringbuilder-concatenation-performance/  StringBuilder Class (System.Text)  https://msdn.microsoft.com/en- us//library/system.text.stringbuilder.aspx 36
  • 37.
    REFERENCE  文章-StringBuilder與String的字串相接效能大車拼 - 黑暗執行緒 http://blog.darkthread.net/blogs/darkthreadtw/archive/20 09/09/07/article-stringbuilder-vs-string.aspx  Performance considerations for strings in C# - CodeProject  http://www.codeproject.com/Articles/10318/Performance -considerations-for-strings-in-C  Improving String Handling Performance in .NET Framework Applications  https://msdn.microsoft.com/en- us/library/aa302329.aspx?f=255&MSPPError=- 2147217396 37
  • 38.
    REFERENCE  Introduction toProgramming with C# / Java Books » Chapter 13. Strings and Text Processing  http://www.introprogramming.info/english-intro-csharp- book/read-online/chapter-13-strings-and-text- processing/ 38
  • 39.
  • 40.

Editor's Notes

  • #31 在這些條件下考慮使用 String 類別: - 當應用程式對字串進行變更的數目很小。 在這些情況下, StringBuilder 不可能在 String 中提供無關緊要的效能改善。 - 當您執行串連作業固定數字,特別是字串常值時。 在這種情況下,編譯器可以結合串連作業至單一作業。 - 當建置字串時,您必須執行大量搜尋。 StringBuilder 類別表示搜尋方法 (例如 IndexOf 或 StartsWith。 您必須將 StringBuilder物件轉換成這些作業的 String ,因此,這可能使 StringBuilder 的效能優勢失去效用。 如需詳細資訊,請參閱 搜尋 StringBuilder 物件中的文字 一節。
  • #32 在這些條件下考慮使用 StringBuilder 類別: - 在設計階段中,當您希望應用程式對字串做變更 (例如,當您使用迴圈串連包含使用者輸入字串的亂數)。 - 當您希望您的應用程式進行大量資料的變更。