string in .net

40
STRING IN .NET Larry Nung

Upload: larry-nung

Post on 15-Jul-2015

51 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: String in .net

STRING IN .NETLarry Nung

Page 2: String in .net

AGENDA

String

String operations

“”& String.Empty

Null & Empty check

String pool

String property

StringBuilder

Reference

Q & A

2

Page 3: String in .net

STRING

3

Page 4: String in .net

STRING

[SerializableAttribute] [ComVisibleAttribute(true)]

public sealed class String : IComparable,

ICloneable, IConvertible, IComparable<string>,

IEnumerable<char>, IEnumerable,

IEquatable<string>

4

Page 5: String in .net

STRING

[SerializableAttribute] [ComVisibleAttribute(true)]

public sealed class String : IComparable,

ICloneable, IConvertible, IComparable<string>,

IEnumerable<char>, IEnumerable,

IEquatable<string>

5

Page 6: String in .net

STRING

6

Page 7: String in .net

STRING

7

Page 8: String in .net

STRING OPERATIONS

8

Page 9: String in .net

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:\\Blog\\LevelUp";

var str6 = @"c:\Blog\LevelUp";

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

Page 10: String in .net

“”& STRING.EMPTY

10

Page 11: String in .net

“” & STRING.EMPTY

11

Page 12: String in .net

“” & 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

Page 13: String in .net

“” & 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()

Page 14: String in .net

“” & 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()

Page 15: String in .net

NULL & EMPTY CHECK

15

Page 16: String in .net

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

Page 17: String in .net

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

Page 18: String in .net

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

Page 19: String in .net

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

Page 20: String in .net

STRING POOL

20

Page 21: String in .net

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

Page 22: String in .net

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

Page 23: String in .net

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

Page 24: String in .net

STRING PROPERTY

24

Page 25: String in .net

STRING PROPERTY

internal class Program

{

public String Name { get; set; }

}

25

Page 26: String in .net

STRING PROPERTY

internal class Program

{

public String Name { get; set; }

}

26

Page 27: String in .net

STRING PROPERTY

internal class Program

{

public String Name { get; set; }

}

27

Page 28: String in .net

STRING PROPERTY

internal class Program

{

private String _name;

public String Name

{

get { return _name ?? String.Empty; }

set { _name = value; }

}

}

28

Page 29: String in .net

STRINGBUILDER

29

Page 30: String in .net

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

Page 31: String in .net

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

Page 32: String in .net

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

Page 33: String in .net

REFERENCE

33

Page 34: String in .net

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

Page 35: String in .net

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

Page 36: String in .net

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

Page 37: String in .net

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=-

214721739637

Page 38: String in .net

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

Page 39: String in .net

Q&A39

Page 40: String in .net

QUESTION & ANSWER

40