4 ms·
I highly doubt that javac produces terrible bytecode.
by vips7L 5y ago
I highly doubt that javac produces terrible bytecode.
- kllrnohj 5y agoI highly doubt you've ever looked at it then. javac more or less intentionally doesn't do any optimizations, it leaves it all for the job of the JIT at runtime. It doesn't do either class-local optimizations nor whole-program / LTO-equivalent optimizations. Things like proguard offer both, and hence why they can so easily claim things like +20% performance. There's a lot of low-hanging fruit in javac's output, at the cost of needing a map file to reconstruct source mappings of course (although Java could of course integrate this into the class files if it wanted, it would just rather invest more or less exclusively in the JIT & GC). Here for example: https://godbolt.org/z/4nzPY3h57 https://godbolt.org/z/4nzPY3h57 javac doesn't even bother to resolve that static field at compile time, which wouldn't even have observable side effects. Nope, just blindly emits a static initializer to invoke square(2) at runtime. Or for a real fun one, enums: https://godbolt.org/z/xjbYvc8dx https://godbolt.org/z/xjbYvc8dx Now some of that is necessary to handle all the stuff other classes could do with the enum, but some of it is just unnecessary. Like building the values array, which invokevirtuals all the ordinals of all the enum values. Ordinals the compiler already knew, since it's literally in the same .class file further up (and these are always in the same .class file, they are in lock-step, so there's again no observable difference if the values array was defined with constants instead of invoking ordinals on each field). And then the trivial switch statement there isn't optimized at all, either, which again wouldn't be observable (compare against what eg. gcc would produce: https://godbolt.org/z/414rGjbE1 https://godbolt.org/z/414rGjbE1 ) Further note that these examples are both static initializers, which means the JIT never "fixes" these (and thus instead perpetually contribute to slow startup). So if javac was going to bother with any attempt to optimize at all, you'd think it'd be here.
- vips7L 5y agoWhile those are low hanging fruit and I want to see more things like that done (I'd cry for more aot scalar replacement), I don't think those are examples of "bad bytecode". Bad bytecode is the kludge of byte code you get when you try to write the same thing in kotlin: https://godbolt.org/z/9sGa6csa6 https://godbolt.org/z/9sGa6csa6
- kllrnohj 5y agoThis would be the same thing in kotlin: https://godbolt.org/z/dq86ezsKd https://godbolt.org/z/dq86ezsKd And the bytecode is of comparable quality to javac's.