On Mon, 2002-11-11 at 10:18, Peter B. West wrote: > Jeremias, > > This was a serious question, really. Joerg, when he gets back, might > like to comment on this, because it was as a result of some of his input > that I first realised there was a significant cost associated with such > Java fundamentals as instanceof and type casting. Those discussions > gave me much food for thought. So I'll rephrase the question: what, if > anything, is the cost of using the interface instead of the implementation?
There is very little difference between casting and the instanceof operator. Both are a single op in the bytecode (use javap to look at the generated byte code). The speed of the operations are largely determined by the vm (no shit sherlock :)). For a look at the op codes here is a cheesy bit of code. public class Casting { public void test() { Cast1 testInstance = new Cast2(); if (testInstance instanceof Cast2) { System.out.println("Instance of Cast2"); } // cast to subclass Cast2 subClassVersion = (Cast2) testInstance; // cast to interface CastInterface interfaceFromCast1Version = (CastInterface) testInstance; // cast to interface from implementing class CastInterface interfaceFromCast2Version = subClassVersion; testInstance = subClassVersion; } public interface CastInterface { CastInterface getInstance(); } public static class Cast1 { public String foo; } public static class Cast2 extends Cast1 implements CastInterface { public CastInterface getInstance() { return this; } } } and the resulting bytecode for the test method Method void test() 0 new #2 <Class Casting. Cast2> 3 dup 4 invokespecial #3 <Method Casting. Cast2()> 7 astore_1 8 aload_1 9 instanceof #2 <Class Casting. Cast2> 12 ifeq 23 15 getstatic #4 <Field java.io.PrintStream out> 18 ldc #5 <String "Instance of Cast2"> 20 invokevirtual #6 <Method void println(java.lang.String)> 23 aload_1 24 checkcast #2 <Class Casting. Cast2> 27 astore_2 28 aload_1 29 checkcast #7 <Interface Casting. CastInterface> 32 astore_3 33 aload_2 34 astore 4 36 aload_2 37 astore_1 38 return op 8 - 12 deal with the instanceof test op 23 - 27 are the class cast op 28 - 32 are the interface cast op 33 - 34 are the interface assign op 36 - 37 are the class assign the casting operations invoke one extra opcode. Castiong and Performace The pattern I use is to expose the objects via their interface but internal method access the implementation class. This allows external use without casting, leave me to decide which concrete implementation is more applicable. A good example of this is ArrayList vs LinkedList; simply expose List and determine the concrete class that is suited to the situation, if you get it wrong you can replace the concrete without violating your external contracts. Because java lacks templates (bring on 1.5) there will always be a cost associated with generic collection usage (in most cases you have to cast to get access to the information you want). The only place I take a second look at casting then is in large loops (where the negative opcode jump usually costs a lot more than the cast) instanceof usage always worries me a little, it can be an indication that there is a problem in encapsulation and interface provision. The most common usage is when the interface is used as a marker interface (eg serializable). The "correctness" of this is a point that can be debated. I've seen people skipping the instanceof check and doing a speculative cast and empty catch. On older vms this was sometimes faster, in my recent tests this is not the case. My advice, don't do it. Optimization - know the outcomes but leave it until the end. When you code, understand what a cast will do, understand how to use StringBuffers and Strings, don't apply an optimization unless it's blatantly obvious. I've seem many cases where developers have heard that something is a performance problem, heard about the solution then apply that solution everywhere without understanding the performance issue. Often this leads to no improvement in speed but always leads to increased problems in code maintenance (StringBuffer usage is a classic example). When you do optimize do it with a profiler and profile a couple of vms. What is an improvement in one is not always an improvement in the other. Unwinding loops will usually come well before casting. Enough rambling about casting and one final point on interfaces. Use them on every published method you can. They will allow you to tune the internals of your class without effecting the published contract. -k. > Peter > > Peter B. West wrote: > > Jeremias, > > > > I have no objection at all, as long as it costs nothing. It is free, > > isn't it? > > > > Jeremias Maerki wrote: > > > >> Fellow FOP developers, > >> > >> would you mind using the interface instead of the implementation where > >> possible? Map instead of HashMap, List instead of ArrayList. I've seen > >> this habit in a number of places and not only by Keiron! I've made it a > >> habit to follow this pattern > > -- > Peter B. West [EMAIL PROTECTED] http://www.powerup.com.au/~pbwest/ > "Lord, to whom shall we go?" > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, email: [EMAIL PROTECTED] > -- If you don't test then your code is only a collection of bugs which apparently behave like a working program. Website: http://www.rocketred.com.au/blogs/kevin/ --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]