4

Now I'm writing an ORM Framework and very care about performance.

In this Framework , I have to use instanceof and Class.isAssignableFrom to check type compability.

So I have a little doubt about the performance of instanceof and Class.isAssignableFrom

How slow exactly it is?

jackalope
  • 1,554
  • 3
  • 17
  • 37

3 Answers3

7

instanceof is supposed to be faster, it's one bytecode operation

public static void main(String[] args) {
        boolean res1 = args instanceof Object;

bytecode

ALOAD 0
INSTANCEOF java/lang/Object
ISTORE 1

compare to

boolean res2 = Object.class.isAssignableFrom(args.getClass());

bytecode

LDC Ljava/lang/Object;.class
ALOAD 0
INVOKEVIRTUAL java/lang/Object.getClass()Ljava/lang/Class;
INVOKEVIRTUAL java/lang/Class.isAssignableFrom(Ljava/lang/Class;)Z
ISTORE 2
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • Yes you compared instanceof and isAssignableFrom – jackalope Jan 07 '13 at 05:41
  • 1
    But I still don't know the implements of `instanceof` – jackalope Jan 07 '13 at 06:14
  • 1
    Unfortunately, looking at the bytecodes doesn't tell you how the `instanceof` is actually implemented. The real performance-determining stuff is in the native code emitted by the JIT compiler. – Stephen C Jan 07 '13 at 07:07
  • Yes it all depends on JVM / JIT. But the bytecode is the same for all JVMs. So, we can switch off the optimization (-Xint on my JVM) and say that this code is faster (slower) than that code in principle and the rest depends on JVM – Evgeniy Dorofeev Jan 07 '13 at 07:28
  • @EvgeniyDorofeev - `-Xint` doesn't just switch off optimization. It disables JIT compilation, and runs the bytecodes entirely using the interpreter. You simply cannot draw any sound conclusions about the performance of JIT compiled code from the performance of interpreted code ... or vice versa. Not in principle, not in practice. – Stephen C Jan 07 '13 at 13:34
3

How instanceof is implemented inside JAVA?

The short answer is that it is platform dependent.

The long answer is that you should be able to find out how it is implemented by writing a test case that uses instanceof, running it in a loop to ensure it gets JIT compiled, and then dumping and examining the native code.

However, I don't think this is going to be particularly instructive. What you really want to know is whether instanceof or Class.isAssignableFrom is faster. You can measure this by careful micro-benchmarking.

FWIW, I predict that you will find that instanceof is faster. (I expect that the JIT compiler would be able to optimize instanceof in ways that it couldn't optimize the reflective version.)

But lastly, I'd suggest that you don't waste your time with this level of optimization at this stage. Code this using instanceof, and wait until you have some profiling data that tells you that your instanceof usage is really a performance bottleneck. (It is all very well to "care about performance" ... but in reality there are more important things that you need to get right BEFORE performance becomes a key issue.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

1st of all, if youre going to micro-benchmark this, at least run a large loop and average, because youre seeing a lot of noise in your timing.
having said that, yes, reflection is slow. if you can design around it and use anything else, do it.
for example, if the set of classes you'll work with is small and known in advance, keep them in a Map<Class,[Something]> and look them up there - you'll need all subclasses to be in that map, but the lookup will be much faster than an instanceof (thats basically how a lot of fast serialization libraries avoid reflection)
if you dont want to (of cant) build this map in advance you can build it as a cache at runtime and then you'll need the instanceOf call only once per new class

radai
  • 23,949
  • 10
  • 71
  • 115
  • question is not about solution. It is about how the operator instanceOf works – Narendra Pathai Jan 07 '13 at 05:14
  • eventually he'll realize its slow, he cant touch the implementation, and he has to get around it... – radai Jan 07 '13 at 06:35
  • instanceOf is not slow in most JVMs it is getting optimized with each version of java. JVM uses Class Hierarchy Analysis and optimizes most of the instanceOf calls IMO. – Narendra Pathai Jan 07 '13 at 09:30
  • @Narendra Pathai - yet most fast serialization libraries (kryo, for example) take great pride in (and improve performance by) getting rid of it. i agree that for non-frequent usage you wont feel it, but if youre using it alot, its noticeable. – radai Jan 07 '13 at 09:33
  • http://stackoverflow.com/questions/12386789/how-is-instanceof-implemented-in-modern-jvm-implementations i think it is cheap. Also i could not find any well known authors stating that using instanceof is heavy – Narendra Pathai Jan 07 '13 at 09:48
  • @ - http://oreilly.com/catalog/javarmi/chapter/ch10.html look under "performance issues": "There are three main performance problems with serialization: it depends on reflection, it has an incredibly verbose ...". so yeah, its getting better, but things will always be faster if you work around it. also, the mere existence of things like http://code.google.com/p/reflectasm/ is a clue. – radai Jan 07 '13 at 10:02
  • I agree to the fact that if the design allows you MUST change it first, but in some cases you have to fall back to instanceof operator. For example: In one of my projects I had to extend Thread class and then when I wanted to check if it is instance of my class, I had to use it :( If you are extending the library then there is no option I guess. – Narendra Pathai Jan 07 '13 at 10:10