Platinum Partner
java,persistence,tips and tricks

Relative Performance of Three Approaches to toString()

I put together a quick experiment to compare the relative performance of three approaches to providing toString():  generated by Eclipse, Apache Reflection, and XML Marshalling.  All three approaches support inheritance.

The traditional toString() implementation was fastest, but also least maintainable.  The Apache based relflection approach was the slowest.  While marshalling is about 6 tmes slower, it requires no maintenance and may be worth considering; it will cause log bloat when formatted output is used.

Summary:

Executing 20000 runs

Eclipse generated toString() total elapsed time 141 ms.  Average: 7 usec.

Apache based reflection total elapsed time 1481 ms.  Average: 74 usec.

XML marshalling total elapsed time 828 ms.  Average: 41 usec.

<code>

package tutorial;

import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.Date;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;

/**
 * Compare relative performance results of various approaches to implementing toString()
 *
 * @author greg totsline
 *
 */
public class ToStringPerformance extends ToStringParent {
 
 private int x = 1;
 private float y = 4.4f;
 private long z = 123456;
 private Date date = new Date();
 private String stringData = "some string data";
 private String[] stringArray = {"one", "two", "three"};
 
 private JAXBContext context;
 
 public ToStringPerformance()
 {
 try {
 context = JAXBContext.newInstance(ToStringPerformance.class);
 } catch (JAXBException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 }

 /**
  * @param args number of runs to perform
  */
 public static void main(String[] args) {
 
 int numRuns = 0;
 
 if (args.length == 0)
 {
 numRuns = 10000;  // default
 }
 else
 {
 numRuns = Integer.parseInt(args[0]);
 }
 System.out.println("Executing " + numRuns + " runs");
 
 ToStringPerformance perfTester = new ToStringPerformance();
 
 /**
  *  load class dependencies by doing an initial call so overhead is not included in measured execution times that follow
  */
 testApacheRelection(perfTester);
 perfTester.toString();
 perfTester.testMarshallToXML(perfTester, ToStringPerformance.class);
 System.nanoTime();
 
 long startTime = System.nanoTime();
 for(int i = 0; i < numRuns; i++)
 { 
  perfTester.toString();   
 }
 long estimatedTime = System.nanoTime() - startTime;
 System.out.println("Eclipse generated toString() total elapsed time " + estimatedTime / 1000000 + " ms.  Average: " + (estimatedTime / 1000) / numRuns + " usec.");
 
 startTime = System.nanoTime();
 for(int i = 0; i < numRuns; i++)
 { 
  testApacheRelection(perfTester);   
 }
 estimatedTime = System.nanoTime() - startTime;
 System.out.println("Apache based reflection total elapsed time " + estimatedTime / 1000000 + " ms.  Average: " + (estimatedTime / 1000) / numRuns + " usec.");
 
 startTime = System.nanoTime();
 for(int i = 0; i < numRuns; i++)
 {
 perfTester.testMarshallToXML(perfTester, ToStringPerformance.class);
 }
 estimatedTime = System.nanoTime() - startTime;
 System.out.println("XML marshalling total elapsed time " + estimatedTime / 1000000 + " ms.  Average: " + (estimatedTime / 1000) / numRuns + " usec.");
 
 
 }
 
 /**
  * Apache based reflection approach to toString()
  * @param perfTester
  * @return
  */
 private static String testApacheRelection(ToStringPerformance perfTester) {
 String result = ReflectionToStringBuilder.toString(perfTester);
 return result;
 
 }

 /**
  * Eclpise generated
  * @see tutorial.ToStringParent#toString()
  */
 @Override
 public String toString() {
 String baseClass = super.toString();
 return baseClass + " ToStringPerformance [x=" + x + ", y=" + y + ", z=" + z
 + ", date=" + date + ", stringData=" + stringData
 + ", stringArray=" + Arrays.toString(stringArray) + "]";
 }


 /**
  * XML marshalled approach to toString()
  * @param objectToBeMarshalled
  * @param clazz
  * @return
  */
 public <T> String testMarshallToXML(T objectToBeMarshalled, Class<T> clazz)
 {
 ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
 String outputString = null;
  try
  {
  Marshaller marshaller = context.createMarshaller();
  marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
 
  marshaller.marshal(new JAXBElement<T>(new QName("", clazz.getSimpleName()),
   clazz, objectToBeMarshalled), baos);
 
  outputString = baos.toString();
 
  }
  catch (JAXBException e) {
  e.printStackTrace();
  }
  return outputString;
 }
 

 public int getX() {
 return x;
 }

 public void setX(int x) {
 this.x = x;
 }

 public float getY() {
 return y;
 }

 public void setY(float y) {
 this.y = y;
 }

 public long getZ() {
 return z;
 }

 public void setZ(long z) {
 this.z = z;
 }

 public Date getDate() {
 return date;
 }

 public void setDate(Date date) {
 this.date = date;
 }

 public String getStringData() {
 return stringData;
 }

 public void setStringData(String stringData) {
 this.stringData = stringData;
 }

 public String[] getStringArray() {
 return stringArray;
 }

 public void setStringArray(String[] stringArray) {
 this.stringArray = stringArray;
 }

</code>

 

package tutorial;

import java.math.BigDecimal;

public class ToStringParent
{
 int j = 1;
 float k = 3.14f;
 double l = 1.234567;
 BigDecimal bigD = new BigDecimal("5551212.1234");
 public int getJ() {
 return j;
 }
 public void setJ(int j) {
 this.j = j;
 }
 public float getK() {
 return k;
 }
 public void setK(float k) {
 this.k = k;
 }
 public double getL() {
 return l;
 }
 public void setL(double l) {
 this.l = l;
 }
 public BigDecimal getBigD() {
 return bigD;
 }
 public void setBigD(BigDecimal bigD) {
 this.bigD = bigD;
 }
 
 @Override
 public String toString() {
 return "ToStringParent [j=" + j + ", k=" + k + ", l=" + l + ", bigD="
 + bigD + "]";
 }
 
 
}

 
}


 

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}