Return-Path: Delivered-To: apmail-ws-axis-dev-archive@ws.apache.org Received: (qmail 65121 invoked by uid 500); 7 Jul 2003 20:09:11 -0000 Mailing-List: contact axis-dev-help@ws.apache.org; run by ezmlm Precedence: bulk Reply-To: axis-dev@ws.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list axis-dev@ws.apache.org Received: (qmail 65110 invoked from network); 7 Jul 2003 20:09:11 -0000 Message-ID: <4FE9AD0A3D28CE42A163544072FE867601E301F3@msgsw55cacah01.wellsfargo.com> From: Eric.D.Friedman@wellsfargo.com To: axis-dev@ws.apache.org Subject: RE: cvs commit: xml-axis/java/src/org/apache/axis AxisFault.java Date: Mon, 7 Jul 2003 13:08:09 -0700 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2653.19) Content-Type: multipart/mixed; boundary="----_=_NextPart_000_01C344C3.7C9F6C00" X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_000_01C344C3.7C9F6C00 Content-Type: text/plain; charset="iso-8859-1" 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:tomj@macromedia.com] Sent: Monday, July 07, 2003 11:58 AM To: 'axis-dev@ws.apache.org' 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: ericf@apache.org [mailto:ericf@apache.org] Sent: Friday, June 27, 2003 1:43 AM To: xml-axis-cvs@apache.org 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(); } /** ------_=_NextPart_000_01C344C3.7C9F6C00 Content-Type: application/octet-stream; name="test.java" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="test.java" public class test {=0A= static int variable;=0A= =0A= static String concat() {=0A= String m =3D "";=0A= =0A= m +=3D "a";=0A= m +=3D makeString();=0A= m +=3D "b";=0A= m +=3D "c";=0A= return m;=0A= }=0A= =0A= static String append() {=0A= StringBuffer b =3D new StringBuffer();=0A= b.append("a");=0A= b.append(makeString());=0A= b.append("b");=0A= b.append("c");=0A= return b.toString();=0A= }=0A= =0A= static String makeString() {=0A= return "some" + variable++;=0A= }=0A= }=0A= ------_=_NextPart_000_01C344C3.7C9F6C00 Content-Type: text/plain; name="javap-test.txt" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="javap-test.txt" Compiled from test.java=0A= public class test extends java.lang.Object {=0A= static int variable;=0A= public test();=0A= static java.lang.String concat();=0A= static java.lang.String append();=0A= static java.lang.String makeString();=0A= }=0A= =0A= Method test()=0A= 0 aload_0=0A= 1 invokespecial #1 =0A= 4 return=0A= =0A= Method java.lang.String concat()=0A= 0 ldc #2 =0A= 2 astore_0=0A= 3 new #3 =0A= 6 dup=0A= 7 invokespecial #4 =0A= 10 aload_0=0A= 11 invokevirtual #5 =0A= 14 ldc #6 =0A= 16 invokevirtual #5 =0A= 19 invokevirtual #7 =0A= 22 astore_0=0A= 23 new #3 =0A= 26 dup=0A= 27 invokespecial #4 =0A= 30 aload_0=0A= 31 invokevirtual #5 =0A= 34 invokestatic #8 =0A= 37 invokevirtual #5 =0A= 40 invokevirtual #7 =0A= 43 astore_0=0A= 44 new #3 =0A= 47 dup=0A= 48 invokespecial #4 =0A= 51 aload_0=0A= 52 invokevirtual #5 =0A= 55 ldc #9 =0A= 57 invokevirtual #5 =0A= 60 invokevirtual #7 =0A= 63 astore_0=0A= 64 new #3 =0A= 67 dup=0A= 68 invokespecial #4 =0A= 71 aload_0=0A= 72 invokevirtual #5 =0A= 75 ldc #10 =0A= 77 invokevirtual #5 =0A= 80 invokevirtual #7 =0A= 83 astore_0=0A= 84 aload_0=0A= 85 areturn=0A= =0A= Method java.lang.String append()=0A= 0 new #3 =0A= 3 dup=0A= 4 invokespecial #4 =0A= 7 astore_0=0A= 8 aload_0=0A= 9 ldc #6 =0A= 11 invokevirtual #5 =0A= 14 pop=0A= 15 aload_0=0A= 16 invokestatic #8 =0A= 19 invokevirtual #5 =0A= 22 pop=0A= 23 aload_0=0A= 24 ldc #9 =0A= 26 invokevirtual #5 =0A= 29 pop=0A= 30 aload_0=0A= 31 ldc #10 =0A= 33 invokevirtual #5 =0A= 36 pop=0A= 37 aload_0=0A= 38 invokevirtual #7 =0A= 41 areturn=0A= =0A= Method java.lang.String makeString()=0A= 0 new #3 =0A= 3 dup=0A= 4 invokespecial #4 =0A= 7 ldc #11 =0A= 9 invokevirtual #5 =0A= 12 getstatic #12 =0A= 15 dup=0A= 16 iconst_1=0A= 17 iadd=0A= 18 putstatic #12 =0A= 21 invokevirtual #13 =0A= 24 invokevirtual #7 =0A= 27 areturn=0A= ------_=_NextPart_000_01C344C3.7C9F6C00--