Chris,

The "Micro performance benchmarking" using Java is danger, because of JIT's optimization may "overwhelm any detectable differences in underlying performance"[1], so I agree with you that the example probably exaggerates effect of exception.

On the other hand, we all know exception throwing does introduce considerable performance overhead, at least the required stack frame may affect JIT's work(as your analysis), so the example is trustworthy in some sense.

[1] http://www-128.ibm.com/developerworks/library/j-perf12053.html

Chris Gray wrote:
On Sunday 26 March 2006 21:10, Geir Magnusson Jr wrote:

I threw together a toy program when I got back to hotel.  I called a
method that did a minor amount of work (increment the int arg and return
it).  Then I created one that did the same, but then threw an exception.
  Then I did one that threw an exception in which string concat was
used.  Finally, one that thew an exception in which a StringBuffer was
used.

I found, for 5000000 iterations on a  1.86G Pentium M under WinXP using
Sun's 1.4.2_10

C:\dev\eclipse\workspace\playspace\java>java -classpath . SpeedTest
test1 - no exception : 16 millis
test2 - exception, static string: 11859 millis
test3 - exception string concat : 13516 millis
test4 - exception stringbuffert : 14125 millis

This simple example probably exaggerates the effect of the exception - test1 is probably so trivial that the JIT compiler probably optimises it to almost nothing, while the other tests require e.g. a stack frame in which the exception can be thrown. It would be interesting to see the results on some other VMs (including gcj). That being said, these numbers do indicate how relying on exceptions for normal flow of execution can seriously damage performance.

I guess we don't get much benefit of using stringbuffer to replace only
one concat (or the compiler is smart enough to do that itself anyway...

String concatenations are translated to StringBuffer (or StringBuilder) operations by the compiler - there is no strcat opcode. If you're building up a string in stages, e.g.
  String s = "foo:";
  if (bar) s += "bar";
  else s += "baz"
  ...etc. ...
then it's worth replacing s by a StringBuffer and doing an explicit toString() at the end:
  StringBuffer sb = new StringBuffer("foo");
  if (bar) sb.append("bar");
  else sb.append("baz");
  ...etc. ...
  String s = sb.toString();
because otherwise the compiler generates code to convert the String to a StringBuffer and back at every stage. But if you're just writing
  "Hello " + name + ", how are you?"
then you save nothing by converting this to
  new StringBuffer("Hello ").append(name).append(", how are you?");
because the generated bytecode is the same.

Chris



--
Paulex Yang
China Software Development Lab
IBM


Reply via email to