Hi Tom,

Would that it were so, but Java's handling of concatenation is woefully
suboptimal where variables are involved.  I'm attaching a couple of files as
examples of this.  The first is a simple class which implements the same
string creation code in two ways: once using concatenation operations, and
again using StringBuffer.append() operations.  The second file is the output
of the bytecode disassembler on the compiled class.  You'll note that the
bytecodes for the concat() method contain repeated calls to new
StringBuffer() and then to toString() -- one for each instance of the
overloaded "+=" operator.  The result is a lot of extra GC thrash for
methods that use the concat() approach.

Eric



-----Original Message-----
From: Tom Jordahl [mailto:[EMAIL PROTECTED]
Sent: Monday, July 07, 2003 11:58 AM
To: '[EMAIL PROTECTED]'
Subject: RE: cvs commit: xml-axis/java/src/org/apache/axis
AxisFault.java


Eric,

My understanding was that Java would "take care of that" when it encountered
string concatenation.  It would convert the x = a + b + c + .. + z; in to
code that would do the "smart" appending.

And the other way was easier to read. :-)

P.S. Welcome to Open Source!
--
Tom Jordahl
Macromedia Server Development

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 
Sent: Friday, June 27, 2003 1:43 AM
To: [EMAIL PROTECTED]
Subject: cvs commit: xml-axis/java/src/org/apache/axis AxisFault.java

ericf       2003/06/26 22:43:03

  Modified:    java/src/org/apache/axis AxisFault.java
  Log:
  replaced extensive String concatenation code with equivalent
  StringBuffer.append code to reduce object creation
  
  Revision  Changes    Path
  1.80      +32 -38    xml-axis/java/src/org/apache/axis/AxisFault.java
  
  Index: AxisFault.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/AxisFault.java,v
  retrieving revision 1.79
  retrieving revision 1.80
  diff -u -r1.79 -r1.80
  --- AxisFault.java    29 May 2003 11:59:56 -0000      1.79
  +++ AxisFault.java    27 Jun 2003 05:43:03 -0000      1.80
  @@ -313,49 +313,43 @@
        */
       public String dumpToString()
       {
  -        String details = new String();
  -
  +        StringBuffer buf = new StringBuffer("AxisFault");
  +        buf.append(JavaUtils.LS);
  +        buf.append(" faultCode: ");
  +        buf.append(XMLUtils.xmlEncodeString(faultCode.toString()));
  +        buf.append(JavaUtils.LS);
  +        buf.append(" faultSubcode: ");
  +        if (faultSubCode != null) {
  +            for (int i = 0; i < faultSubCode.size(); i++) {
  +                buf.append(JavaUtils.LS);
  +                buf.append(faultSubCode.elementAt(i).toString());
  +            }
  +        }
  +        buf.append(JavaUtils.LS);
  +        buf.append(" faultString: ");
  +        buf.append(XMLUtils.xmlEncodeString(faultString));
  +        buf.append(JavaUtils.LS);
  +        buf.append(" faultActor: ");
  +        buf.append(XMLUtils.xmlEncodeString(faultActor));
  +        buf.append(JavaUtils.LS);
  +        buf.append(" faultNode: ");
  +        buf.append(XMLUtils.xmlEncodeString(faultNode));
  +        buf.append(JavaUtils.LS);
  +        buf.append(" faultDetail: ");
           if (faultDetails != null) {
               for (int i=0; i < faultDetails.size(); i++) {
                   Element e = (Element) faultDetails.get(i);
  -                String namespace= e.getNamespaceURI();
  -                if(namespace==null) {
  -                    namespace="";
  -                }
  -                String partname= e.getLocalName();
  -                if(partname==null) {
  -                    partname=e.getNodeName();
  -                }
  -                details += JavaUtils.LS
  -                          + "\t{" + namespace + "}"
  -                          + partname + ": "
  -                          + XMLUtils.getInnerXMLString(e);
  -            }
  -        }
  -
  -        String subCodes = new String();
  -        if (faultSubCode != null) {
  -            for (int i = 0; i < faultSubCode.size(); i++) {
  -                subCodes += JavaUtils.LS
  -                            + (QName)faultSubCode.elementAt(i);
  +                buf.append(JavaUtils.LS);
  +                buf.append("\t{");
  +                buf.append(null == e.getNamespaceURI() ? "" :
e.getNamespaceURI());
  +                buf.append("}");
  +                buf.append(null == e.getLocalName() ? "" :
e.getLocalName());
  +                buf.append(":");
  +                buf.append(XMLUtils.getInnerXMLString(e));
               }
           }
  -        //encode everything except details and subcodes, which are
already
  -        //dealt with one way or another.
  -        String code= XMLUtils.xmlEncodeString(faultCode.toString());
  -        String errorString= XMLUtils.xmlEncodeString(faultString);
  -        String actor= XMLUtils.xmlEncodeString(faultActor);
  -        String node= XMLUtils.xmlEncodeString(faultNode);
  -
  -
  -        return "AxisFault" + JavaUtils.LS
  -            + " faultCode: " + code + JavaUtils.LS
  -            + " faultSubcode: " + subCodes + JavaUtils.LS
  -            + " faultString: " + errorString + JavaUtils.LS
  -            + " faultActor: " + actor + JavaUtils.LS
  -            + " faultNode: " + node + JavaUtils.LS
  -            + " faultDetail: " + details + JavaUtils.LS
  -            ;
  +        buf.append(JavaUtils.LS);
  +        return buf.toString();
       }
   
       /**
  
  
  

Attachment: test.java
Description: Binary data

Compiled from test.java
public class test extends java.lang.Object {
    static int variable;
    public test();
    static java.lang.String concat();
    static java.lang.String append();
    static java.lang.String makeString();
}

Method test()
   0 aload_0
   1 invokespecial #1 <Method java.lang.Object()>
   4 return

Method java.lang.String concat()
   0 ldc #2 <String "">
   2 astore_0
   3 new #3 <Class java.lang.StringBuffer>
   6 dup
   7 invokespecial #4 <Method java.lang.StringBuffer()>
  10 aload_0
  11 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  14 ldc #6 <String "a">
  16 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  19 invokevirtual #7 <Method java.lang.String toString()>
  22 astore_0
  23 new #3 <Class java.lang.StringBuffer>
  26 dup
  27 invokespecial #4 <Method java.lang.StringBuffer()>
  30 aload_0
  31 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  34 invokestatic #8 <Method java.lang.String makeString()>
  37 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  40 invokevirtual #7 <Method java.lang.String toString()>
  43 astore_0
  44 new #3 <Class java.lang.StringBuffer>
  47 dup
  48 invokespecial #4 <Method java.lang.StringBuffer()>
  51 aload_0
  52 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  55 ldc #9 <String "b">
  57 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  60 invokevirtual #7 <Method java.lang.String toString()>
  63 astore_0
  64 new #3 <Class java.lang.StringBuffer>
  67 dup
  68 invokespecial #4 <Method java.lang.StringBuffer()>
  71 aload_0
  72 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  75 ldc #10 <String "c">
  77 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  80 invokevirtual #7 <Method java.lang.String toString()>
  83 astore_0
  84 aload_0
  85 areturn

Method java.lang.String append()
   0 new #3 <Class java.lang.StringBuffer>
   3 dup
   4 invokespecial #4 <Method java.lang.StringBuffer()>
   7 astore_0
   8 aload_0
   9 ldc #6 <String "a">
  11 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  14 pop
  15 aload_0
  16 invokestatic #8 <Method java.lang.String makeString()>
  19 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  22 pop
  23 aload_0
  24 ldc #9 <String "b">
  26 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  29 pop
  30 aload_0
  31 ldc #10 <String "c">
  33 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  36 pop
  37 aload_0
  38 invokevirtual #7 <Method java.lang.String toString()>
  41 areturn

Method java.lang.String makeString()
   0 new #3 <Class java.lang.StringBuffer>
   3 dup
   4 invokespecial #4 <Method java.lang.StringBuffer()>
   7 ldc #11 <String "some">
   9 invokevirtual #5 <Method java.lang.StringBuffer append(java.lang.String)>
  12 getstatic #12 <Field int variable>
  15 dup
  16 iconst_1
  17 iadd
  18 putstatic #12 <Field int variable>
  21 invokevirtual #13 <Method java.lang.StringBuffer append(int)>
  24 invokevirtual #7 <Method java.lang.String toString()>
  27 areturn

Reply via email to