6

I was just reading about scala's implementation of generics specialization , and it really caught my attention the increase of speed they achieved with this feature. I was wondering what other features have the languages that target the java vm implemented that actually made them perform better than java? I know that the further the generated code moves away from java, the further its performance drops. So I really wonder what other features can a language implement to achieve better performance in java.

Please don't answer this question talking about scala's really nice features on top of java, I'm talking strictly about performance.

Also if you have suggestions that still weren't implemented, please do answer!

Thank you!

Waneck
  • 2,450
  • 1
  • 19
  • 31
  • "I know that the further the generated code moves away from java, the further its performance drops." - I don't think this is necessarily true. Some languages lend themselves better to optimization than others, but it doesn't really have anything to do with how close to Java that language is. – Jesper Jan 27 '11 at 09:46
  • Yes, really it isn't necessarily true, but it's true that the vm engineers optimize better for the use cases that are most common by the java language – Waneck Jan 27 '11 at 18:18
  • I'm not sure whether the question is even correct. The generated code is bytecode, as the javacode, compiled, is bytecode, so after compilation, I thought, they are indistinguishable. AFAIK, the languages as jRuby, jython etc. just use much more reflection, which makes the programs slower. – user unknown Jan 28 '11 at 03:37
  • yes, but you can optimize this bytecode so it generates faster running JIT code ;) – Waneck Jan 28 '11 at 10:22

3 Answers3

13

Scala does support tail-call optimization, which Java, through the JVM alone, don't fully support yet.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • +1. That is a very cool optimization, and if the JVM eventually gets support for it as well, that would be even nicer. – Thilo Jan 27 '11 at 08:41
  • that's really a great optimization! Thanks! – Waneck Jan 28 '11 at 10:25
  • it seems this and the generics specialization are the main optimizations they perform. Great to know, and great reference! Thanks! – Waneck Jan 28 '11 at 17:53
5

Scala optimizes things like

val nullSafeToString = "" + foo

to

val nullSafeToString = String.valueOf(foo)

Java doesn't, in Java it looks like

val nullSafeToString = new StringBuilder("").append(foo)

which takes 4 times more bytecode than Scala's simpler code and creates a new StringBuilder instance and an useless String.

On the one side the JVM was made to support the things they had planned to use in Java, even if the JVM only executes bytecode.

There are features which are missing for ages to better support functional (tailcalls) and untyped languages (InvokeDynamic).

But on the other side I'm surprised how painless the JIT compiler can optimize heavily abstracted code and layers of indirection away and end up with code performing as fast as Java code.

I think that "Pimp My Library" pattern wouldn't be that popular if the JVM couldn't remove the instance creations of these simple implicit + class RichFoo patterns with escape analysis.

soc
  • 27,983
  • 20
  • 111
  • 215
3

Maybe this is too trivial/old/well-known but the Java compiler optimizes String literals and concatenations using a String pool and StringBuilders:

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

will actually be closer to

 String a = "a";
 String b = a;
 String a_b = "aa";
 String c = new StringBuilder(a_b).append(someUserInput).toString();

or maybe even (not sure)

 String a_b = "aa";
 String a = a_b.substring(0,1);
 String b = a;
 String c = new StringBuilder(a_b).append(someUserInput).toString();

Also, the focus of optimization for the Java compiler has shifted from compilation to bytecode (javac) to the compilation from bytecode to machine code (Hotspot). I think there used to be more optimizations in javac, but they have found that to be a bit premature given that Hotspot can do a much more thorough job here (and draw on runtime knowledge about actual hardware and usage patterns).

Another interesting aspect of this is that Hotspot optimizations can improve the performance long after the code was written and compiled. For example, the StringBuilder optimization above used to use the (slightly less efficient) StringBuffer class before Java 5. In order to get the latest improvements, you would need to recompile the code (which is still better than having hand-optimized to use StringBuffer before, in which case you would actually need to update the code).

Thilo
  • 257,207
  • 101
  • 511
  • 656
  • yeah, I know that it's sort of against java's philosophy to optimize its bytecode. But the thing is, that if you are using a lot a feature that isn't very well optimized by the java compiler yet, you are out of luck - generics specialization being one of those optimizations. I really wonder what could be done to implement structs-like behavior, for example, in java. – Waneck Jan 27 '11 at 07:58
  • I guess Scala has the potential to share a lot of other values (the immutable ones); does it? – Raphael Jan 27 '11 at 08:42