Worrying about my web application's performances, I am wondering which of "if/else" or switch statement is better regarding performance?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
I totally agree with the opinion that premature optimization is something to avoid.
But it's true that the Java VM has special bytecodes which could be used for switch()'s.
See WM Spec (lookupswitch and tableswitch)
So there could be some performance gains, if the code is part of the performance CPU graph.
For most
switch
and mostif-then-else
blocks, I can't imagine that there are any appreciable or significant performance related concerns.But here's the thing: if you're using a
switch
block, its very use suggests that you're switching on a value taken from a set of constants known at compile time. In this case, you really shouldn't be usingswitch
statements at all if you can use anenum
with constant-specific methods.Compared to a
switch
statement, an enum provides better type safety and code that is easier to maintain. Enums can be designed so that if a constant is added to the set of constants, your code won't compile without providing a constant-specific method for the new value. On the other hand, forgetting to add a newcase
to aswitch
block can sometimes only be caught at run time if you're lucky enough to have set your block up to throw an exception.Performance between
switch
and anenum
constant-specific method should not be significantly different, but the latter is more readable, safer, and easier to maintain.That's micro optimization and premature optimization, which are evil. Rather worry about readabililty and maintainability of the code in question. If there are more than two
if/else
blocks glued together or its size is unpredictable, then you may highly consider aswitch
statement.Alternatively, you can also grab Polymorphism. First create some interface:
And get hold of all implementations in some
Map
. You can do this either statically or dynamically:Finally replace the
if/else
orswitch
by something like this (leaving trivial checks like nullpointers aside):It might be microslower than
if/else
orswitch
, but the code is at least far better maintainable.As you're talking about webapplications, you can make use of
HttpServletRequest#getPathInfo()
as action key (eventually write some more code to split the last part of pathinfo away in a loop until an action is found). You can find here similar answers:If you're worrying about Java EE webapplication performance in general, then you may find this article useful as well. There are other areas which gives a much more performance gain than only (micro)optimizing the raw Java code.
It's extremely unlikely that an if/else or a switch is going to be the source of your performance woes. If you're having performance problems, you should do a performance profiling analysis first to determine where the slow spots are. Premature optimization is the root of all evil!
Nevertheless, it's possible to talk about the relative performance of switch vs. if/else with the Java compiler optimizations. First note that in Java, switch statements operate on a very limited domain -- integers. In general, you can view a switch statement as follows:
where
c_0
,c_1
, ..., andc_N
are integral numbers that are targets of the switch statement, and<condition>
must resolve to an integer expression.If this set is "dense" -- that is, (max(ci) + 1 - min(ci)) / n > α, where 0 < k < α < 1, where
k
is larger than some empirical value, a jump table can be generated, which is highly efficient.If this set is not very dense, but n >= β, a binary search tree can find the target in O(2 * log(n)) which is still efficient too.
For all other cases, a switch statement is exactly as efficient as the equivalent series of if/else statements. The precise values of α and β depend on a number of factors and are determined by the compiler's code-optimization module.
Finally, of course, if the domain of
<condition>
is not the integers, a switch statement is completely useless.Use switch!
I hate to maintain if-else-blocks! Have a test:
My C# standard code for benchmarking
According to Cliff Click in his 2009 Java One talk A Crash Course in Modern Hardware:
You can get his full slides here.
Cliff gives an example (finishing on Slide 30) showing that even with the CPU doing register-renaming, branch prediction, and speculative execution, it's only able to start 7 operations in 4 clock cycles before having to block due to two cache misses which take 300 clock cycles to return.
So he says to speed up your program you shouldn't be looking at this sort of minor issue, but on larger ones such as whether you're making unnecessary data format conversions, such as converting "SOAP → XML → DOM → SQL → …" which "passes all the data through the cache".