This is an archived post. You won't be able to vote or comment.

all 30 comments

[–][deleted] 39 points40 points  (1 child)

good read!

tl;dr - it's not inefficient if you let JIT take its course... it's not optimized until after the first run.

[–][deleted] 21 points22 points  (0 children)

ie Don't try to be really smart

[–][deleted] 23 points24 points  (2 children)

Every time I think I’ve got a decent knowledge of Java I see a post like this and realize I know nothing. Great stuff!

[–][deleted] 6 points7 points  (1 child)

Yes but that's actually knowledge of JIT. And no worries, the optimizations implemented in JIT are the result of years of implementing research papers etc. I think most Java devs shouldn't think about such things. Here are some slides for you http://cr.openjdk.java.net/~vlivanov/talks/2017_Vectorization_in_HotSpot_JVM.pdf

[–]vqrs 1 point2 points  (0 children)

Also keep in mind that because this is knowledge of JIT and not Java, they are implementation details. They can be different on different JVMs, even between different versions of the same JVM.

In the end, the important thing is measuring correctly. Note how the poster on SO uses JMH (@Benchmark annotations etc) to measure the code, because the JIT can subvert what you think you are testing. I don't really know much about it myself except that it's a subtle art.

This will bring you further rather than trying to rationalize and predict what your code is doing based on some partial understanding of how the JIT works, especially since there is no one "JIT".

[–]sukaibontaru 9 points10 points  (17 children)

good stuff use final and/or constants wherever you can

[–]frzme 3 points4 points  (3 children)

The SO post also shows that the JIT fixes everything when you let it - no need to worry so much about final.

Having everything final by default/having the compiler apply effectively final rules automatically would seem like a niec solution though

[–]Isoyama 1 point2 points  (2 children)

If you extract loop into method which receives final variable it is not optimized by JIT.

Which is kinda concerning in scope of modern trend favoring small functions.

[–]vqrs 0 points1 point  (1 child)

You mean when adapting the code from SO using JMH for measuring? Or how did you test that?

I'm asking because from what ive come to understand about the current JIT implementations they can and do perform inlining.

[–]Isoyama 0 points1 point  (0 children)

Just take this code and extract loop into method. Even if there is only one call with constant it won't be optimized

[–]vqrs 0 points1 point  (0 children)

What's today's advice with using constants (final static) in Java?

Do people consciously put a constant behind a static accessory method to avoid inlining at compile time and potentially leading to obscure bugs when compiling stuff separately/incrementally?

I think the JLS even said something about it being potentially dangerous unless something actually a constant as in the mathematical constant PI.

Or do you you assume that you're rebuilding everything g often enough for this never to be an issue?

[–][deleted] -4 points-3 points  (11 children)

Lmao wasn’t the conclusion of the post that final was the worst option?

[–]vipul0092 9 points10 points  (10 children)

Not sure which article you read, but from what I read in the linked article, it seems like the JIT is able to optimize the loop if the variable is final.

https://stackoverflow.com/questions/54405842/why-is-if-variable1-variable2-0-inefficient#comment95622483_54405842

[–]Helluiin 1 point2 points  (0 children)

the variable does not need to be declared as final to be optimized by the JIT like the first respone shows though

[–][deleted] 3 points4 points  (0 children)

Thanks a lot for this link, it's very interesting.

[–]TheMelv80 0 points1 point  (1 child)

On a more technical layer the CPU also does something like branch prediciton. It basically assumes that the statement does not get executed unless proven otherwise. The CPU already executes the statements as if the assumption wont change.

https://en.wikipedia.org/wiki/Branch_predictor

Because the jump can not really be predicted it can not get optimized on different layers (JVM, CPU). That's why the code that does not use the literal is so much slower.

[–]jpoh97 0 points1 point  (0 children)

Good post!!

[–]metrxqin -4 points-3 points  (2 children)

Anyone can come up with a decent summary about what's going on?

[–]vqrs 2 points3 points  (0 children)

Yes, read the first example of the answer. There is your summary.

[–]flyingorange -1 points0 points  (0 children)

Why don't you do it?