Do you optimize?

T

Thomas Kellerer

Your test is not the same as a constant concatenation. Basically

String s = "some" + "thing";

(not in a loop or something)

will be expanded by the compiler. Not variable assignment elsewhere in the
code.

The test you have here is exactly the situation where programmer's
optimization *does* matter.

Regards
Thomas


Hendrik said:
When the compiler expands the + macro to calls to StringBuffer and
combines adjacent literal strings, this becomes:


How do you explain these results:
Testing string concat...

Testing stringbuffer...

Results:

concat time: 2333ms total

buffer time: 20ms total

Does not look like ist becomes the same bytecode, though it should be identical. Using JDK 1.4.2 by the way...

This is the test class:
-- BEGIN CODE --
public class Test {

public static final int CYCLES = 10000;

public static void main(String argv[]) {

String s1 = new String("test");

String s2 = new String(" me");

String s3 = s1;

StringBuffer s4 = new StringBuffer(s1);

long time, time1, time2;

System.out.println("Testing string concat...");

time = System.currentTimeMillis();

for (int i=0; i<CYCLES; i++) {

s3 = s3 + s2;

}

time1 = System.currentTimeMillis() - time;

System.out.println("Testing stringbuffer...");


time = System.currentTimeMillis();

for (int i=0; i<CYCLES; i++) {

s4 = s4.append(s2);

}

time2 = System.currentTimeMillis() - time;


System.out.println("Results:");

System.out.println("concat time: " + time1 + "ms total");

System.out.println("buffer time: " + time2 + "ms total");

}

}

-- END CODE --
 
P

pete kirkham

Hendrik said:
Ah, thanks for that thorough explanation!

Oddly enough, removing the aload and pop slows things done (I had to do
100 times as many iterations on the length optimized loops to get >
single digit timings)

over a dozen runs, these were typical:

concat time: 0.2028000ms per call
buffer time: 0.0002760ms per call
length optimized buffer time: 0.0001975ms per call
op-code-reduced buffer time: 0.0002030ms per call

(OS X, Java HotSpot(TM) Client VM (build 1.4.1_01-14, mixed mode))

I guess the HotSpot compiler may be mapping variables to registers but
the operand stack to memory.


Pete
 
D

Dale King

Take this code for example:

String sql = "select id, name, age from employees"
+ "where name like '%" + name + "%'";

My colleague will optmise this code:

String sql = new StringBuffer(
"select id, name, age from employees")
.append("where name like '%")
.append(name)
.append("%'");

Your colleague's version may actually be much, much slower! I remember
this from a thread in an Eclipse newsgroup. For code like:

String a = "b" + c + "d";

Javac will generate:

String a = new StringBuffer().append( "b" ).append( c ).append( "d"
).toString();

But the compiler in Eclipse generated this which is the same as your
colleague's "optimization":

String a = new StringBuffer( "b" ).append( c ).append( "d" ).toString();

Seem like a good optimization? Well it turned out that with the 1.4 JVM
this "optimized" version was an order of magnitude slower than that
produced by javac. See this thread from eclipse newsgroups for code and
numbers:

http://dev.eclipse.org/newslists/news.eclipse.tools/msg29601.html

So contrary to those telling you to optimize every line, don't do it. You
always have to measure. If you don't measure the only thing you can be
sure of is that you have made your code harder to read.
 
J

John C. Bollinger

Roedy said:
You need a good estimate for size of the final string to ace out
simple +. Otherwise the StringBuffer has to take time out to grow
itself.

True. One should also recognize that the Java compiler handles
compile-time constant expressions and subexpressions, including string
concatenations. There are only two run-time concatenations in the
example code fragment, no matter how many ways the constant text is
broken up. The example "optimized" code performs three StringBuffer
appends.

In this case I'd probably use a PreparedStatement anyway.


John Bollinger
(e-mail address removed)
 
D

Daniel Dyer

How do you explain these results:
Testing string concat...

Testing stringbuffer...

Results:

concat time: 2333ms total

buffer time: 20ms total

That's because the compiler has to instantiate a new StringBuffer for the
"+" whereas you're using the same one each time.

Dan.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,610
Members
45,255
Latest member
TopCryptoTwitterChannels

Latest Threads

Top