Code details refactoring: Please point out my code (1)

Source: Internet
Author: User

"Please kindly advise on my code" is an irregular routine activity in our group. With code review and detail refactoring as the main line, you can freely express your opinions and suggestions, it is also a storm of thinking. It makes sense to summarize and record this activity. Today I launched 4 short codes, all of which are representative. Today, I will make a simple summary and share with you the reconstruction of one of the code snippets.

First, let's look at the target code:

 1 public static string TestA(List<string> items) 2 { 3     var builder = new StringBuilder(); 4  5     foreach (var item in items) 6     { 7         if (builder.Length > 0) 8         { 9             builder.Append("|");10             builder.Append(item);11         }12         else builder.Append(item);13     }14 15     return builder.ToString();16 }

Here I use C # as an example. In fact, the language is the same. The optimization techniques we will talk about are common in most programming environments. For the above Code, the following optimization suggestions are collected in total.

Recommendation 1: code reusability

We can see that if... else... the clause contains a section "builder. append (item); "the code is repeated. You can change the process to make them appear only once. The reconstruction result is as follows:

1 foreach (VAR item in items) 2 {3 if (builder. length> 0) builder. append ("|"); // removed braces 4 5 builder. append (item); 6}
Recommendation 2: Performance Optimization

We know that the stringbuilder class constructor has a capacity parameter, which means the pre-allocated memory size during stringbuilder object initialization. If you can set a value appropriately, it will be helpful for improving performance. This can reduce the number of memory allocations. By default, stringbuilder doubles the memory requirements in the form of a power of 2 (for us, this process is automatic ).

Recommendation 3: Performance Optimization

We recommend that you split foreach into a manual append and a for loop to avoid if judgment within foreach. The CPU clock cycle can be greatly reduced when the data volume is large. This is a good suggestion! The code after reconstruction is as follows:

1 public static string TESTA (list <string> items) 2 {3 // here is a hypothetical capacity-optimized value, in actual operation, we need to continuously test and optimize 4 var builder = new stringbuilder (100000); 5 6 builder. append (items [0]); 7 8 for (VAR I = 1; I <items. count; I ++) 9 {10 var item = items [I]; 11 12 builder. append ("|"); 13 builder. append (item); 14} 15 16 return builder. tostring (); 17}
Suggestion 4: Memory Optimization

In fact, it combines recommendation 2 and recommendation 3, as shown below:

1 public static string TESTA (list <string> items) 2 {3 var length = items. sum (t => T. length); 4 5 Length + = (items. count-1); 6 7 if (length = 0) return string. empty; 8 9 // calculate the value of capacity 10 var builder = new stringbuilder (length); 11 12 builder. append (items [0]); 13 14 for (VAR I = 1; I <items. count; I ++) 15 {16 builder. append ("|"); 17 builder. append (items [I]); // eliminates a previous local variable and reduces memory allocation by 18} 19 20 return builder. tostring (); 21}
My replies

In fact, I did not give this question to investigate Performance Optimization, memory optimization, and other issues. However, I am very pleased that the monkeys can come up with various tricks to solve the problem! At least everyone is involved. They are all thinking! This is a good thing!

After reading this article, I believe that you have discovered that the original business logic of the question is to use the "|" string in a string set to join, "|" cannot appear on both sides of the result string ". Therefore, I hope to have my shoes come up with the following refactoring suggestions:

1 public static string TestB(List<string> items) 2 { 3     return String.Join("|", items);4 }

Do you feel that I am so embarrassed?

Yes! Code detail refactoring is not only about optimization and code writing, coding experience, coding specifications, but also about business logic! What is programming? Programming is a means and process for processing data. There may be many ways to achieve the same results. For us, we need to pick out the most simple and easy-to-use methods from these methods, the performance difference should not be too big.

Performance tests are often highly random, so we have to perform tests multiple times at different orders of magnitude and then collect an average result (preferably remove the maximum and minimum values) for comparison. As for the size of performance differences, we all think that the difference is "not big" or "No difference" within the same order of magnitude. We must be cautious when we exceed two orders of magnitude!

This article comes with the test code I have compiled. You can download it and run it for comparison. I randomly selected a test result for your reference:

Test data preparation is complete. Press any key to continue ...... Itemcount stringbuilder string. Join 1 1.851500 0.318600 10 0.027500 0.064400 100 0.225500 0.261600 1000 10.104700 2.324100 10000 19.039900 20.094800 100000 216.185100 251.624600 1000000 2364.580300 3401.948900 10000000 22862.921600 33593.679800 completed the test!

We can see that the performance difference between our suggestion 4 and the string. Join method is actually very small and negligible. Generally, who will process a set of millions or tens of millions?

As for why the two methods are not very different, we only need to look at the string. the implementation of the join method is known through. net reflector after decompilation, we found that its implementation also uses a solution similar to recommendation 4:

 1 [SecuritySafeCritical] 2 public static unsafe string Join(string separator, string[] value, int startIndex, int count) 3 { 4     if (value == null) throw new ArgumentNullException("value"); 5     if (startIndex < 0) throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex")); 6     if (count < 0) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NegativeCount")); 7     if (startIndex > (value.Length - count)) throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer")); 8     if (separator == null) separator = Empty; 9     if (count == 0) return Empty;10             11     var length = 0;12     var num2 = (startIndex + count) - 1;13             14     for (var i = startIndex; i <= num2; i++) if (value[i] != null) length += value[i].Length;15             16     length += (count - 1)*separator.Length;17             18     if ((length < 0) || ((length + 1) < 0)) throw new OutOfMemoryException();19     if (length == 0) return Empty;20             21     string str = FastAllocateString(length);22             23     fixed (char* chRef = &str.m_firstChar)24     {25         var buffer = new UnSafeCharBuffer(chRef, length);26         buffer.AppendString(value[startIndex]);27                 28         for (var j = startIndex + 1; j <= num2; j++)29         {30             buffer.AppendString(separator);31             buffer.AppendString(value[j]);32         }33     }34 35     return str;36 }

The code is no longer interpreted, so you can understand it slowly.

What I want to tell you in this article is: Code detail refactoring should not only stay on the surface of the language, but may sometimes get unexpected results if you go deep into the business logic!

Download Code:

Code details structure -string.join.zip

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.