3

Recently I bumped into a situation where a static code analysis tool (PMD) complainted about a switch statement that had too few branches. It suggested turning it into an if statement, that I did not wanted to do because I knew that soon more cases will be added. But I wondered if the javac performs such an optimization or not. I decompiled the code using JAD but it showed still a switch. Is it possible that this is optimized runtime by the JIT?

Update: Please do not be misleaded by the context of my question. I'm not asking about PMD, I'm not asking about the need for micro-optimisation, etc. The question is clearly only this: does the current (Oracle 1.6.x) JVM implementation contain a JIT that deals with switches with too few branches or not.

jabal
  • 11,987
  • 12
  • 51
  • 99

4 Answers4

3

The way to determine how the JIT compiler is optimizing switch statements is either:

  • read the JIT compiler source code (OpenJDK 6 and 7 are open source), or
  • run the JVM with the switch that tells it to dump the JIT compiled code for the classes of interest to a file.

Note that like all questions related to performance and optimization, the answer depends on the hardware platform and the JVM vendor and version.

Reference: Disassemble Java JIT compiled native bytecode


If this Question is "mere idle curiosity", so be it.

However, it should also be pointed out that rewriting your code to use switch or if for performance reasons is probably a bad idea and/or a waste of time.

  • It is probably a waste of time because the chances are that the difference in time (if any) between the original and hand optimized versions will be insignificant.

  • It is a bad idea because, your optimization may only be helpful for specific hardware and JVM combinations. On others, it may have no effect ... or even be an anti-optimization.

In short, even if you know how the JIT optimizer handles this, you probably shouldn't be taking it into account in your programming.

(The exception of course is when you have a real measurable performance problem, and profiling points to (say) a 3-branch switch as being one of the bottlenecks.)

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • thanks a lot, your comments tell me that nor optimization matters, nor does the code style matter, in the real world, the performance and bottleneck matter, for the other things, let the JVM considers – Harry_T Aug 23 '22 at 07:50
2

If you compiled it in debug mode, it is normal that when you decompile it, you still get the switch. Otherwise, any debugging attempt would miss some information such as line number and the original instruction flow.
You could thus try to compile in production mode and see what the decompilation result would be.

However, a switch statement, especially if it is expected to grow, is generally considered as a code smell and should be evaluated as a good candidate for a refactoring.

gizmo
  • 11,819
  • 6
  • 44
  • 61
1

As for after your clarification on what the question is.

Since this denepnds so strongly on the hardware and the JVM (JVMs using the Java trademark may be developed by companies other than Oracle as long as they adhere to the JVM specification) Id say the only valid method would be to make speed tests.

Cut out a chunk of code, lock it in a loop for a considerable amount of repetitions, check the time before and after execution of the loop. Repeat for both solutions (switch and if)

This may seem simplistic and silly, but it actually works, and is a lot faster than decompiling, reading through bytecode and memory dumps etc.


You have to remember, that Java actually uses Virtual Machines and bytecode. Im pretty sure this is all handled and optimized. We are using high level languages to AVOID such micromanagement and optimization that youre asking about

On a more general note, I think you are trying to optimize a bit too early. If you know there are going to be more cases in that switch, why bother at all? Did you run a profiler? If not, its no use optimizing. "Premature optimization is the root of all evil". You might be optimizing a part of code that actually isnt the bottleneck, incresing code complexity and wasting your own time on writing code that does not contribute in any way.

I dont know what type of app you are making, but a rule of thumb says that clarity is king, and you usually should choose simpler, more elegant, self-documenting solution.

K.L.
  • 2,419
  • 1
  • 21
  • 26
  • The question has nothing to do with early/unnecessary optimization. I'll surely not do that, just curious about the way JIT works. – jabal Sep 12 '12 at 11:54
0

The javac performance almost no optimisations. All the optimisations are performed at runtime using the JIT. Unless you know you have a performance problem, I would assume you don't.

What the PMD is complaining about is clarity. e.g.

if (a == 5) {
  // something
} else {
  // something else
}

is clearer than

switch(a) {
   case 5:
       // something
       break;
   default:
       // something else
       break;
}
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130