Comparison of performance optimization schemes for Java ToString

Source: Internet
Author: User

Who cares about the performance of ToString? No one! Unless you have a lot of data in bulk processing, using ToString produces a lot of logs. Then you investigate why it's so slow to realize that most of the ToString methods use introspection, which can actually be optimized.

But first let's take a look at what Javadoc recalls object.tostring should do: "Returns the string representation of the object, which must be concise but well-articulated. It is recommended that all subclasses override this method. The most interesting thing here is "concise" and "informative". Our beloved Ides often generate equals/hashcode/tostring of these methods for us, and we usually do not control them. In addition, these Ides provide many ways to generate our own ToString: String connections (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 what kind of tostring implementation will be more efficient, do not guess, but to test! At this point you need to use JMH. I've written about it on my blog, so there's no more detail about how JMH works.

In this benchmark, I created a complex object graph (using inheritance, collections, and so on), and I used all the different implementations of ToString generated by the IDE to see which performance was better. Just one rule of thumb: brevity. Regardless of which technology you use (below), generating tosting for some attributes or all attributes (including inheritance, dependencies, or collections) can have a huge impact on performance.

connect string with +

Let's start with the most efficient approach: connect strings with +. Once this is considered to be the use of evil ("Do not use + connection string!!! "), has become very cool and efficient! Now the JVM compiler (most of the time) compiles the + into a string builder. So, don't hesitate, use it. The only drawback is that the null value is not processed and you need to handle it yourself.

Take a look at the average performance calculated using JMH in the annotations below.

 Public String toString () {    return "myobject{" +            "att1= '" + att1 + "+            ", att2= ' "+ att2 +" +< c6/> ", att3= '" + att3 + "+            Super. toString ();} // Average Performance with JMH (OPS/S) // (min, avg, max) = (140772,314, 142075,167, 143844,717) // average performance measured using the JMH // (min, avg, max) = (140772,314, 142075,167, 143844,717)
Connecting Strings with Objects.tostring

The

Java SE 7 brings up the objects class and some of its static methods. The advantage of objects.tostring is that it can handle null values and can even set a default value for NULL. Its performance is slightly lower than the previous, but the null value can be processed:

 Public String toString () {    return "myobject{" +            "att1= '" + objects.tostring (ATT1) + "+            ", att2 = ' "+ objects.tostring (ATT2) +            " + ", att3= '" + objects.tostring (ATT3) + "+            Super. toString ();}  //  Average Performance with JMH (OPS/S)//  (min, avg, max) = (138790,233, 14079 1,365, 142031,847)//  average performance measured with JMH //  (min, avg, max) = (138790,233, 140791,365, 142031,847)

StringBuilder

Another technique is to use StringBuilder. It's hard to tell which technology is better. As I said earlier, I've used complex object graphs (ATT1, att2, and ATT3 variables for readability), JMH gives more or less the same result. The following three technologies are very close to performance.

 PublicString toString () {FinalStringBuilder SB =NewStringBuilder ("myobject{"); Sb.append ("att1="). Append (ATT1). Append ("');    Sb.append (", att2= '"). Append (ATT2). Append (' ');    Sb.append (", att3= '"). Append (ATT3). Append (' '); Sb.append (Super. toString ()); returnsb.tostring ();}//Average Performance with JMH (OPS/S)//(min, avg, max) = (96073,645, 141463,438, 146205,910)//average performance measured using the JMH//(min, avg, max) = (96073,645, 141463,438, 146205,910)
Guava

Guava has some helper classes: one of them can help you generate ToString. This is less than pure JDK API performance, but it can provide you with some additional services (I mean Guava):

 PublicString toString () {returnObjects.tostringhelper ( This). Add ("Att1", ATT1). Add ("Att2", ATT2). Add ("Att3", ATT3). Add ("Super",Super. ToString ()). ToString ();}//Average Performance with JMH (OPS/S)//(min, avg, max) = (97049,043, 110111,808, 114878,137)//average performance measured using the JMH//(min, avg, max) = (97049,043, 110111,808, 114878,137)
Commons Lang3

Commons Lang3 has some techniques to generate ToString: from builder to Introspector. As you can guess, introspection is easier to use, with less code, but with poor performance:

 PublicString toString () {return NewTostringbuilder ( This). Append ("Att1", ATT1). Append ("Att2", Att2). Append ("Att3", ATT3). Append ("Super",Super. ToString ()). ToString ();}//Average Performance with JMH (OPS/S)//(min, avg, max) = (73510,509, 75165,552, 76406,370)//average performance measured using the JMH//(min, avg, max) = (73510,509, 75165,552, 76406,370) PublicString toString () {returnTostringbuilder.reflectiontostring ( This, Tostringstyle.short_prefix_style);}//Average Performance with JMH (OPS/S)//(min, avg, max) = (31803,224, 34930,630, 35581,488)//average performance measured using the JMH//(min, avg, max) = (31803,224, 34930,630, 35581,488) PublicString toString () {returnReflectiontostringbuilder.tostring ( This);}//Average Performance with JMH (OPS/S)//(min, avg, max) = (14172,485, 23204,479, 30754,901)//average performance measured using the JMH//(min, avg, max) = (14172,485, 23204,479, 30754,901)
Summarize

Now with JVM optimizations, we can safely use the + to concatenate strings (and use objects.tostring to handle null). With a utility class built into the JDK, no external framework is required to handle null values. Therefore, the out-of-the-box JDK has better performance than the other technologies described in this article (if you have other frameworks/technologies, please leave a comment and I'll try it).

As a summary, here is a table of average performance data obtained from JMH (descending from the most efficient)

Use of Technology average number of Operations/sec
Connect strings with ' + ' 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, this is important if you call the ToString method often. Otherwise, performance is really not a thing.

Comparison of performance optimization schemes for Java ToString

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.