cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael McKibben <mmckib...@ncube.com>
Subject Re: StringBuffers and String Concatenation
Date Fri, 26 Oct 2001 23:23:12 GMT
What really stinks about using a StringBuffer (and therefore the +
operator) is that append's are synchronized!! To really see an impact on
performance, use a custom string buffer class that is not thread safe and
use StringBuffers only where thead safety is required.

Regards,

--mike

On Fri, 26 Oct 2001, Sylvain Wallez wrote:

>
> Berin Loritsch a écrit :
> >
> > Friends, going through the source code looking for
> > places to optimize the critical path (i.e. the path
> > taken when no error or log message is performed),
> > I went through adding StringBuffers where there were
> > three or more strings to concatenate.
> >
> > I found an enigma.
> >
> > In several places, where the code was already using
> > a StringBuffer, I found code snippets like this:
> >
> > buffer.append("<" + prefix + ":" + name + "/>");
> >
> > This gets expanded into the much more complex code as
> > follows:
> >
> > buffer.append(
> >     new StringBuffer(
> >         new StringBuffer(
> >             new StringBuffer(
> >                 new StringBuffer("<").append(prefix).toString()
> >             ).append(":").toString()
> >         ).append(name).toString()
> >     ).append("/>").toString()
> > );
> >
> > That means four additional StringBuffers were created
> > behind the scenes.  This is ludicrous when we are already
> > using StringBuffers--and wasteful of resources.
> >
> > Instead, please write the code to explicitly take advantage
> > of the StringBuffer when it is available:
> >
> > buffer.append("<").append(prefix).append(":").append(name).append("/>");
> >
> > This is more respectful of the environment, and is much quicker
> > to execute on any JVM.
> >
> > Please, be mindful in the future.
>
> Berin,
>
> Having once looked at the generated bytecode for string concatenation, I
> came to the conclusion that replacing "+" on Strings by append() on
> StringBuffers is really not worth it as far as performance is concerned,
> apart of course in the above case which involves concatenation in
> appends (and a strange compiler behaviour).
>
> Take the following example. The two methods do exactly the same thing,
> one with String concatenation, and the other one with
> StringBuffer.append().
>
> package proto;
> public class TestSBuff {
>
>     public void test1(int i, String msg) {
>         System.out.println("The value "
>             + "of i is "
>             + i
>             + " and the value of msg is '"
>             + msg
>             + "'");
>     }
>
>     public void test2(int i, String msg) {
>         System.out.println(new StringBuffer("The value ")
>             .append("of i is ")
>             .append(i)
>             .append(" and the value of msg is '")
>             .append(msg)
>             .append("'")
>             .toString());
>     }
> }
>
> Here's the resulting bytecode, output with javap -c :
>
> Compiled from TestSBuff.java
> public class proto.TestSBuff extends java.lang.Object {
>     public proto.TestSBuff();
>     public void test1(int, java.lang.String);
>     public void test2(int, java.lang.String);
> }
>
> Method proto.TestSBuff()
>    0 aload_0
>    1 invokespecial #1 <Method java.lang.Object()>
>    4 return
>
> Method void test1(int, java.lang.String)
>    0 getstatic #2 <Field java.io.PrintStream out>
>    3 new #3 <Class java.lang.StringBuffer>
>    6 dup
>    7 invokespecial #4 <Method java.lang.StringBuffer()>
>   10 ldc #5 <String "The value of i is ">
>   12 invokevirtual #6 <Method java.lang.StringBuffer
> append(java.lang.String)>
>   15 iload_1
>   16 invokevirtual #7 <Method java.lang.StringBuffer append(int)>
>   19 ldc #8 <String " and the value of msg is '">
>   21 invokevirtual #6 <Method java.lang.StringBuffer
> append(java.lang.String)>
>   24 aload_2
>   25 invokevirtual #6 <Method java.lang.StringBuffer
> append(java.lang.String)>
>   28 ldc #9 <String "'">
>   30 invokevirtual #6 <Method java.lang.StringBuffer
> append(java.lang.String)>
>   33 invokevirtual #10 <Method java.lang.String toString()>
>   36 invokevirtual #11 <Method void println(java.lang.String)>
>   39 return
>
> Method void test2(int, java.lang.String)
>    0 getstatic #2 <Field java.io.PrintStream out>
>    3 new #3 <Class java.lang.StringBuffer>
>    6 dup
>    7 ldc #12 <String "The value ">
>    9 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
>   12 ldc #14 <String "of i is ">
>   14 invokevirtual #6 <Method java.lang.StringBuffer
> append(java.lang.String)>
>   17 iload_1
>   18 invokevirtual #7 <Method java.lang.StringBuffer append(int)>
>   21 ldc #8 <String " and the value of msg is '">
>   23 invokevirtual #6 <Method java.lang.StringBuffer
> append(java.lang.String)>
>   26 aload_2
>   27 invokevirtual #6 <Method java.lang.StringBuffer
> append(java.lang.String)>
>   30 ldc #9 <String "'">
>   32 invokevirtual #6 <Method java.lang.StringBuffer
> append(java.lang.String)>
>   35 invokevirtual #10 <Method java.lang.String toString()>
>   38 invokevirtual #11 <Method void println(java.lang.String)>
>   41 return
>
> Two things are shown above :
>
> * String concatenation is translated to StringBuffer.append()
> instructions. The only difference with direct StringBuffer code is that
> the default no-arg StringBuffer() constructor is called and the first
> string is appended like others. I'm not sure this small benefit
> justifies the decreased code readability (and the increased keyboard
> typing ;)
>
> * Constant String concatenation (like "The value " + "of i is ") isn't
> translated to individual StringBuffer.append(), but to a single String
> constant ("The value of i is "). In that case, performance is better
> with String concatenation. This means some of the changes you made on
> code where constant strings are concatenated to allow line-splitting
> (see for example WildcardURIMatcherFactory) are in fact slowing down the
> code !
>
> The conclusion is that StringBuffer is only worth it when the
> concatenation occurs in several statements, or iteratively such as in a
> "for" loop. Otherwhise, single-statement String concatenations can be
> considered equivalent to their StringBuffer translation, but produce
> less readable code.
>
> Sylvain.
>
> --
> Sylvain Wallez
> Anyware Technologies - http://www.anyware-tech.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
> For additional commands, email: cocoon-dev-help@xml.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


Mime
View raw message