Who cares about toString performance ?, Are you concerned about toString performance?

Source: Internet
Author: User

Who cares about toString performance ?, Are you concerned about toString performance?

Who cares about toString performance? No one! Unless you have a large amount of data in batch processing, using toString produces a lot of logs. Then, when you investigate why it is so slow, you will realize that most toString methods use introspection, which can be optimized.

However, let's take a look at what Object. toString should do when Javadoc recalled: "The String Representation of the returned Object must be concise but easy to understand. We recommend that you override this method for all subclasses ". The most interesting here is "concise" and "Detailed ". Our favorite ides often generate equals, hashcode, and toString methods for us, and we usually do not care about them. In addition, these ides provide many ways to generate our own toString: String connection (using the + sign), StringBuffer, StringBuilder, ToStringBuilder (Commons Lang 3), ReflectionToStringBuilder (Commons Lang 3), Guava, or Objects. toString ...... Which one should I choose?

If you want to know which toString implementation method will be more efficient, do not guess, but test it! In this case, you need to use JMH. I once wrote articles about JMH on my blog, so I will not discuss details about how JMH works here.

In this benchmark, I created a complex object graph (using inheritance, set, and so on) and used all the different toString implementation methods generated by IDE, let's see which one has better performance. Just one rule of thumb: concise. No matter which technology you use (as follows), generating toSting for some or all attributes (including inheritance, dependency, or set) will have a huge impact on performance.

Connect strings with +

Let's start with the most efficient method: connect strings with +. This is once considered an evil method of use ("do not use + to connect strings !!!"), It has become cool and efficient! Now the JVM Compiler (most of the time) will compile + into a string builder. So don't hesitate. Just use it. The only drawback is that the null value will not be processed. You need to handle it yourself.

Let's take a look at the average performance calculated using JMH in the following annotations.

1 public String toString () {2 return "MyObject {" + 3 "att1 = '" + att1 + ''' + 4 ", att2 = '"+ att2 + ''' + 5", att3 =' "+ att3 + ''' + 6"} "+ super. toString (); 7} 8 9 // Average performance with JMH (ops/s) 10 // (min, avg, max) = (140772,314,142 143844,717) 11 // average performance tested using JMH 12 // (minimum, average, maximum) = (140772,314,142 143844,717)
Use Objects. toString to connect to a string

Java SE 7 brings the Objects class and some of its static methods. The advantage of Objects. toString is that it can process null values or even set the default value for null. Its performance is slightly lower than the previous one, but the null value can be processed:

1 public String toString () {2 return "MyObject {" + 3 "att1 = '" + Objects. toString (att1) + ''' + 4 ", att2 = '" + Objects. toString (att2) + ''' + 5 ", att3 = '" + Objects. toString (att3) + ''' + 6 "}" + super. toString (); 7} 8 9 // Average performance with JMH (ops/s) 10 // (min, avg, max) = (138790,233,140 791,365, 142031,847) 11 // average performance tested using JMH 12 // (minimum, average, maximum) = (138790,233,140 791,365, 142031,847)
StringBuilder

Another technology is StringBuilder. It is difficult to tell which technology has better performance. As I mentioned earlier, I have used complex object graphs (the names of att1, att2, and att3 variables are for readability). JMH provides more or less identical results. These three technologies are very similar in terms of performance.

1 public String toString () {2 final StringBuilder sb = new StringBuilder ("MyObject {"); 3 sb. append ("att1 = '"). append (att1 ). append ('''); 4 sb. append (", att2 = '"). append (att2 ). append ('''); 5 sb. append (", att3 = '"). append (att3 ). append ('''); 6 sb. append (super. toString (); 7 return sb. toString (); 8} 9 10 // Average performance with JMH (ops/s) 11 // (min, avg, max) = (96073,645,141 463,438, 146205,910) 12 // average performance tested using JMH 13 // (minimum, average, maximum) = (96073,645,141 463,438, 146205,910)
Guava

Guava has some helper classes: one of them can help you generate toString. This is worse than pure jdk api performance, but it can provide you with some additional services (I refer to Guava here)

1 public String toString () {2 return Objects. toStringHelper (this) 3. add ("att1", att1) 4. add ("att2", att2) 5. add ("att3", att3) 6. add ("super", super. toString ()). toString (); 7} 8 9 // Average performance with JMH (ops/s) 10 // (min, avg, max) = (97049,043,110 114878,137) 11 // average performance tested using JMH 12 // (minimum, average, maximum) = (97049,043,110 114878,137)
Commons Lang3

Commons Lang3 has some techniques to generate toString: From builder to introspector. As you have guessed, introspection is easier to use and has fewer code but worse performance:

1 public String toString () {2 return new ToStringBuilder (this) 3. append ("att1", att1) 4. append ("att2", att2) 5. append ("att3", att3) 6. append ("super", super. toString ()). toString (); 7} 8 9 // Average performance with JMH (ops/s) 10 // (min, avg, max) = (73510,509,751 65,552, 76406,370) 11 // average performance tested using JMH 12 // (minimum, average, maximum) = (73510,509,751 65,552, 76406,370) 13 14 public String toString () {15 return ToStringBuilder. reflectionToString (this, ToStringStyle. SHORT_PREFIX_STYLE); 16} 17 18 // Average performance with JMH (ops/s) 19 // (min, avg, max) = (31803,224,349 35581,488) 20 // The average performance tested using JMH 21 // (minimum, average, maximum) = (31803,224,349 35581,488,) 22 23 public String toString () {24 return ReflectionToStringBuilder. toString (this); 25} 26 27 // Average performance with JMH (ops/s) 28 // (min, avg, max) = (14172,485,232 30754,901) 29 // average performance tested using JMH 30 // (minimum, average, maximum) = (14172,485,232 30754,901)
Summary

Now with JVM optimization, we can safely use + to connect strings (and use Objects. toString to process null ). A utility class with built-in JDK does not require an external framework to process null values. Therefore, the out-of-the-box JDK has better performance than other technologies described in this article (if you have other frameworks/technologies, please leave a comment to me to try it out ).

To sum up, the following is a table of average performance data obtained from JMH (descending from the most efficient)

Use Technology Average operation count/second
Use '+' to connect to a string 142.075, 167
String builder 141.463, 438
Objects. toString 140.791, 365
Guava 110.111, 808
ToStringBuilder (append) 75.165, 552
ToStringBuilder (reflectionToString) 34.930, 630
ReflectionToStringBuilder 23.204, 479

Again, if you call the toString method frequently, this is very important. Otherwise, performance is really not a problem.

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.