0

I know that "test it in your app" is a must. Nonetheless, I would like to ask for an analitical insight as well.

I have an in-app instruction queue (as an Array) which elements are processed sequentially. The details are irrelevant. (Consider "instruction" as a virtual instruction, i.e. it is interpreted as such only in terms of my application -- like a small internal Virtual Machine).

The actual question is: which is faster for processing the queue elements -- virtual dispatch provided by Java, or a switch-case?

  1. In the first case, the Array consists of descendants of an own Operation object (or simply of Runnable -- you get the point). In this case, instruction execution is merely calling the Operation.run() override of the object. Virtual dispatch will do the rest -- the run() of the concrete instance will be called.

  2. The Array is a primitive int array, and each element is an instruction code that comes from a contiguous range (e.g. an int between 0..65535). Instruction processing means that the instruction code is interpreted: (A) either via a switch-case statement, or (B) by using an Array (of Operation objects) that is indexed directly by the instruction codes.

In the second case, I suppose switch-case is optimized enough nowadays (especially because I'm using a contiguous range), so we can forget the Array option.

To sum up, which is faster? Adding the interpreting code to the branches of the switch-case, or using the virtual dispatch?

I suppose it breaks down to this: is a switch-case faster or a virtual dispatch? I read that a switch-case can be optimized to a branch table or jump instructions, and I guess in this case it will be possible.

Thomas Calc
  • 2,994
  • 3
  • 30
  • 56
  • It looks liek the solution 2B is exactly the same as the solution 1, but with an additional level of indirection. Java is an OO language. I would go with the first solution, and only try to optimize if needed, and if you have proven that the virtual dispatch is the cause of the performance problem (which I doubt, given that the rest of the API uses OO and polymorphism everywhere). It really looks like you're optimizing prematurely. And this is the root of all evil. – JB Nizet Sep 29 '12 at 15:15
  • I asked for an insight, as I said. I like to know things analytically. I would like to know (independently of everything else) if virtual dispatch or switch-case is faster. I am not afraid that virtual dispatch will cause a performance problem -- I just want to know which approach has a smaller execution time. – Thomas Calc Sep 29 '12 at 15:26
  • switch-case is faster, but your example has nothing to do with this. – auselen Sep 29 '12 at 20:26
  • auselen, what do you mean "it has nothing to do with this"? In what way? I know it's micro-optimization, but why "nothing to do"? My question asked which would be faster (expectably) in this case. You gave an answer, which you state has "nothing to do with it". Could you clarify this? – Thomas Calc Sep 30 '12 at 14:16

2 Answers2

1

Since your switch statement is "dense", my feeling is that it should be faster than a multiple inheritance scheme. Most probably compiler is going to optimize it to a table lookup based on an integer index. Again just my feeling is that, it is more improbable that compiler will be such as fast in (internally) resolving your inheritance scheme in order to execute the 'invokevirtual' opcode in the second alternative... especially if the base class has been inherited in many variants.

johnidis
  • 111
  • 4
0

I think swtich-case is slower (and not as readable), because basically it's the same than a cascaded if/elseif/... so you'd have a lot of comparations here until the correct case-branch is found, whilest with direct access, the correct instruction should be accessible directly. (Hope I understood your question right, with all those hypothetical and theoretical stuff)

Ridcully
  • 23,362
  • 7
  • 71
  • 86
  • Yes, you got the question right, but I disagree -- you mention the naive implementation of switch-case. E.g. here, they mention the compiler greatly optimizes it: http://stackoverflow.com/questions/5582261/performance-of-array-of-functions-over-if-and-switch-statements – Thomas Calc Sep 29 '12 at 15:42
  • So it's not trivial that the switch-case is slower or faster, because a virtual dispatch means a function call as well, while switch-case does not (of course, I know that if the difference was only +1 method call, then it's negligible; in fact, probably even now it's negligible, but I still want an analytical examination to the matter). – Thomas Calc Sep 29 '12 at 15:43
  • Ah, I never thought of this, but this also explains why switch() is only allowed for numeral values. For those, the described 'binary chop' thingy can be applied, but not for strings or other objects. – Ridcully Sep 29 '12 at 17:07