In C #, how do I operate strings correctly ?,

Source: Internet
Author: User
Tags mscorlib

In C #, how do I operate strings correctly ?,

The string should be the most frequently used basic data type in all programming languages. If you are careful with the use, we will pay for the extra performance overhead caused by a string operation. This article will discuss how to avoid such performance overhead from two aspects:
1. Make sure to pack as few items as possible
2. Avoid allocating additional memory space.

First aspect: Make sure to pack as few items as possible

We should be familiar with unpacking. Converting the value type to the reference type is boxing, and converting the reference type to the value type is unpacking. In your own code, you should try to avoid writing unnecessary Packing code. Packing causes performance loss because it requires the following three steps:
• First, memory is allocated for the value type in the managed heap. In addition to the memory allocated by the value type itself, the total memory size also includes the memory occupied by the Type object pointer and synchronous block index.
• Then, copy the value type to the newly allocated heap memory.
• Finally, return the address of the object that has become the reference type.

The following is the simplest Packing code line.

1 object obj = 1;

This line of statements assigns the integer constant 1 to the object type variable obj. It is well known that constant 1 is a value type, the value type is to be placed on the stack, and the object is a reference type, it needs to be placed on the stack; to put the value type on the stack, You need to perform a packing operation.

The IL code of this line of statements is as follows. Note the following annotations:

. Locals init ([0] object objValue) // the above three lines of IL indicate the local variable IL_0000: nopIL_0001: ldc that declares the object type as objValue. i4.s 9 // indicates putting the integer number 9 to the top of the stack IL_0003: box [mscorlib] System. int32 // execute the IL box command and apply for System in the memory heap. the heap space IL_0008: stloc.0 required by Int32 // The variables on the stack Are popped up and stored in a local variable with an index of 0.

The above is the operation to be performed for packing. When the packing operation is performed, it is inevitable to apply for memory space on the stack and copy the value type data on the stack to the requested heap memory space, this must consume memory and cpu resources. Let's take a look at how the unpacking operation is going on:

See the following C # code:

object objValue = 4;int value = (int)objValue;

The above two lines of code will perform a packing operation to pack integer constant 4 into the objValue of the reference type object variable, and then perform another unpacking operation, store the reference variable objValue stored on the stack to the value of the partial integer value type variable.

We also need to look at the IL code:

. Locals init ([0] object objValue, [1] int32 'value') // The above IL declares two partial variables: object-type objValue and int32-type value variables IL_0000: nopIL_0001: ldc. i4.4 // press integer 4 into the stack IL_0002: box [mscorlib] System. int32 // execute the IL box command and apply for System in the memory heap. int32 requires the heap space IL_0007: stloc.0 // The variables on the stack Are popped up and stored in the local variable with the index 0 IL_0008: ldloc.0 // press the local variable with the index 0 (that is, the objValue variable) into the stack IL_0009: unbox. any [mscorlib] System. int32 // execute the IL command unbox. any converts an object of the reference type to System. int32 type IL_000e: stloc.1 // store the data on the stack to the local variable whose index is 1, that is, value.

The binning operation is opposite to the packing operation. It is used to convert the reference type value stored on the stack to the value type and give the value type variable.

The packing and unpacking operations require additional CPU and memory resources. So how can we avoid packing and unpacking? You can use the following methods:
1. Replace ArrayList with a generic set.
2. Use the built-in C # conversion method to convert the value type to the reference type.

Next we will look at the situation where the use of generic and the absence of generic causes packing and unpacking.
1. binning and unboxing operations caused by using a non-generic set

See the following code:

var array = new ArrayList();array.Add(1);array.Add(2);foreach (int value in array){Console.WriteLine(“value is {0}”,value);}

The Code declares an ArrayList object and adds two numbers, 1 and 2 to the ArrayList. Then, use foreach to print the elements in the ArrayList to the console.

During this process, two packing operations and two unpacking operations will occur. When an int type element is added to the ArrayList, when you use foreach to enumerate the int type elements in the ArrayList, The unboxing operation will occur. Convert the object type to the int type and execute the operation on the Console. writeLine, The binning operation is performed twice. This code runs six binning and unboxing operations. If the number of ArrayList elements is large, more operations will be performed for packing and unpacking.

You can use tools such as ILSpy to view the box and unbox commands of the IL code.

2. Use of generic Sets

See the following code:

1 var list = new List<int>();2 list.Add(1);3 list.Add(2);4 5 foreach (int value in list)6 {7 Console.WriteLine("value is {0}", value);8 }

 

The difference between the code in code and the code in 1 is that the set type uses a generic List instead of an ArrayList. We can also view the IL code to view the case of packing and unpacking, the above code is only available on the Console. the WriteLine () method is used to pack data twice without unpacking.

It can be seen that the generic type can avoid unnecessary performance consumption caused by packing and unpacking. Of course, the benefits of the generic type are not limited to this, and the generic type can also increase the readability of the program, make the program easier to reuse and so on.

However, we noticed that when using a generic set, the Console. WriteLine () method still performs two packing operations. Can I optimize these two packing operations? The second method is used to convert the value type to the reference type using the C # built-in conversion method. As follows:

var list = new List<int>();list.Add(1);list.Add(2);foreach (int value in list){Console.WriteLine(string.Format("value is {0}", value.ToString()));}

Check the IL code and find that the packing operation has been completely eliminated. It actually calls the integer ToString method. The prototype of the ToString method is:

public override string ToString(){return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo);}

It converts data from int to string by directly operating the memory, which is much more efficient than packing. Therefore, when using other value types to convert and splice strings, you should avoid using the operator "+", instead of using the ToString method provided by the value type.

Second, avoid allocating extra memory.
For CLR, A string object is a special object. Once assigned, it cannot be changed. Call System. any method in the String class or any operation (such as "=" assignment, "+" concatenation) will create a new String object in the memory, this also means to allocate new memory space for the new object. The following code brings additional runtime overhead.

Private static void Test6 () {string s1 = "abc"; s1 = "123" + s1 + "456"; // three String objects are created in the above two lines of code, and executed a String. contact Method string s2 = 9 + "456"; // This code is packed once and called once. concact method} private static void Test7 () {string s1 = "123" + "abc" + "456"; // The code is equivalent to string s1 = "123abc456 "}

Because the use of the String class will bring significant performance loss in some cases, Microsoft also provides a StringBuilder type to make up for the shortcomings of the String.

StringBuilder does not re-create a String object. Its Efficiency Comes from allocating memory in an unmanaged way in advance. If StringBuilder does not define the length first, the allocated length is 16 by default. If the StringBuilder character length is less than or equal to 16, StringBuilder will not re-allocate the memory. When the StringBuilder character length is greater than 16 and less than 32, StringBuilder will re-allocate the memory to make it a multiple of 16. In the code above, if the length of the pre-determined string is greater than 16, you can set a more appropriate length for it.
Microsoft also provides another method to simplify this operation, that is, using the string. Format method. The string. Format method uses StringBuilder internally to Format strings.

private static void Test9(){string a = "t";string b = "e";string c = "s";string d = "t";StringBuilder sb = new StringBuilder();sb.Append(a);sb.Append(b);sb.Append(c);sb.Append(d);Console.WriteLine(sb.ToString());}private static void Test10(){string a = "t";string b = "e";string c = "s";string d = "t";Console.WriteLine(string.Format("{0}{1}{2}{3}", a, b, c, d));}

Conclusion: how to operate strings correctly:

1. Make sure that there are as few disassembly box operations as possible: use generic, use ToString () to convert the value type to the reference type
2. Avoid allocating extra memory space: Do not use the + =, + operator. Use StringBuilder, String. Format () to link multiple strings.

 

Reference List:

Http://www.cnblogs.com/yukaizhao/archive/2011/10/18/csharp_box_unbox_1.html
Http://www.cnblogs.com/yukaizhao/archive/2011/10/19/csharp_box_unbox_2.html
Writing high-quality code: 157 suggestions for improving C # programs

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.